L2-002 链表去重
解题思路
这里介绍一个特别妙的思路(by 柳婼 , 这是她的个人网站)
-
首先,需要一个 “字母表” 决定去留。
-
在遍历过程中,留下来的数,令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;
}

浙公网安备 33010602011771号