L2-002 链表去重

天梯赛L2-002传送门

解题思路

这里介绍一个特别妙的思路(by 柳婼 , 这是她的个人网站

  1. 首先,需要一个 “字母表” 决定去留。

  2. 在遍历过程中,留下来的数,令num = cnt1++ , 删去的数令num = maxn + cnt2++ ,对于没有用到的数,我们可以令num = 2 * maxn(初始化时)
    最后,sort可将整个数组分成三部分, 留下来的 - 删去的 - 未适用的, 有效长度为cnt1 + cnt2,记为 cnt,随后遍历cnt个节点并输出(注意格式)

非常妙的思想,只用了一个数组却完美储存了两个链表,并且考虑到了每个链表的最大大小,完美分配空间。利用num进行分割,但是本身数组大小并没有改变。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100000;
struct NODE{
    int address;
    int key;
    int next ;
    int num;
}node[maxn];

bool exist[maxn];

int cmpl(NODE a,NODE b)
{
    return a.num < b.num;
}

int main()
{
    int begin ,n , cnt1 = 0 , cnt2 = 0 , a;
    cin>>begin>>n;
    for(int i = 0 ; i < maxn ; i ++)
        {
            node[i].num = 2 * maxn;
        }
    for(int i = 0 ; i < n ; i++)
        {
            cin>>a;
            cin>>node[a].key>>node[a].next;
            node[a].address = a;
        }
    for(int i = begin ; i != -1 ; i = node[i].next)
        {
            if(!exist[abs(node[i].key)])
            {
                exist[abs(node[i].key)] = true;
                node[i].num = cnt1 ++;
            }
            else
            {
                node[i].num = maxn + cnt2 ++;
            }
        }

    sort(node,node + maxn , cmpl);
    int cnt = cnt1 + cnt2;
    for(int i = 0 ; i < cnt ; i ++)
        {
            if(i != cnt1 - 1 && i != cnt - 1)
            {
                printf("%05d %d %05d\n" , node[i].address , node[i].key , node[i+1].address);
                
            }
            else printf("%05d %d -1\n" , node[i].address , node[i].key);
        }
    
    return 0;
}
posted @ 2026-03-14 12:41  shuiwangrenjia  阅读(0)  评论(0)    收藏  举报