Deduplication on a Linked List
Given a singly linked list L with integer keys, you are supposed to remove the nodes with duplicated absolute values of the keys. That is, for each value K, only the first node of which the value or absolute value of its key equals K will be kept. At the mean time, all the removed nodes must be kept in a separate list. For example, given L being 21→-15→-15→-7→15
, you must output 21→-15→-7
, and the removed list -15→15
.
Input Specification
Each input file contains one test case. For each case, the first line contains the address of the first node, and a positive N (≤10^5) which is the total number of nodes. The address of a node is a 5-digit nonnegative integer, and NULL is represented by −1.
Then N lines follow, each describes a node in the format:
where Address is the position of the node, Key is an integer of which absolute value is no more than 10^4, and Next is the position of the next node.
Output Specification
For each case, output the resulting linked list first, then the removed list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input
Sample Output
类似这样的骚操作网上有很多,这里不在引用。本文主要考虑常规思路。思路非常简单,便利链表,如果曾经出现过就插入另一个链表,没出现过就继续,最后得到两个链表,分别是去重后的和重复的。看似比较简单,想把所有情况考虑全也是要花点心思的。
- 重复部分的链表是和原链表顺序是一样的,采用尾插法。需要头、尾两个指针。
- 原链表的头节点是第一个节点,不可能被放入重复链表,那么去重后的链表头节点不变。
- 遍历过程中需要将节点删除(即插入重复链表),所以需要
prev
指针记录去重链表的上一个节点地址,以便修改next
指针。
如果你像我一样以为上面的描述就把所有的情况都考虑完全了,那么欢迎你和我来到BUG的海洋😉
先来看AC的代码
|
|
为啥
while
循环里又套了个while
循环,用if
不就够了么?
此乃第一坑😉
上文说到
prev
指针记录去重链表的上一个节点地址
那么prev
的next
应该是去重链表的下一个地址。而if
得到的仅仅是下一个地址,此时还不知道他是否属于去重链表。这时不能做prev.next=cur
。那什么时候可以呢?当然是map[abs(nodes[cur].key)
为假啦。
好多
-1
看的我头晕
恭喜你,进入了第二坑😉
dupli_head
和dupli_tail
是头尾指针,-1
作为链表为空时的特殊值。插入
dupli
链表后,要把cur.next
置为-1
,表示这是新链表的最后一个节点。为防止链表断裂,用next=cur.next
记住下一个地址。插入重复链表是在
while
循环里进行的,那么就有可能在这里耗光所有的元素。此即if (cur == -1) break;
。当在
while
循环里耗尽所有元素后,已经不可能有新的元素可以作为prev.next
,因此if (cur == -1) { nodes[prev].next = -1; break; }
- 上文说过,原链表的头节点一定是去重链表的头节点。那么当刚访问过头节点时,是不需要对
prev
操作的。即if (prev != -1) nodes[prev].next = cur;
。当然,你也可以直接跳过头节点123map[head]=true;cur = nodes[head].next;prev = head;
怎么样,还觉得考虑所有情况简单么😉