題目
編寫代碼,移除未排序鏈表中的重複節點。保留最開始出現的節點。
示例1:
輸入:[1, 2, 3, 3, 2, 1]
輸出:[1, 2, 3]
示例2:
輸入:[1, 1, 1, 1, 2]
輸出:[1, 2]
提示:
- 鏈表長度在[0, 20000]範圍內。
- 鏈表元素在[0, 20000]範圍內。
進階:
如果不得使用臨時緩衝區,該怎麼解決?
解題思路
遍歷鏈表,用一個哈希集合(HashSet)來存儲所有出現過的節點。
具體地,我們從鏈表的頭節點 head 開始進行遍歷,遍歷的指針記爲 cur。由於頭節點一定不會被刪除,因此我們可以枚舉待刪除節點的前驅節點 cur,那麼當前節點就是 cur.next,後繼節點就是 cur.next.next:
1)如果當前節點的值不在 Set 中,就將值加入 Set,並將指針移動到下一位置。
2)如果當前節點的值已在 Set 中出現過,那麼就刪除當前節點,將當前節點的後繼節點與前驅節點相連。
複雜度分析:
時間複雜度:O(N),其中 N 是給定鏈表中節點的數目。
空間複雜度:O(N)。在最壞情況下,給定鏈表中每個節點都不相同,哈希表中需要存儲所有的 N 個值。
代碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeDuplicateNodes(ListNode head) {
if(head == null){
return head;
}
Set<Integer> set = new HashSet<>();
set.add(head.val);
ListNode cur = head;
while(cur.next != null){
if(!set.contains(cur.next.val)){
set.add(cur.next.val);
cur = cur.next;
}else{
cur.next = cur.next.next;
}
}
return head;
}
}