2.1 Write code to remove duplicates from an unsorted linked list.
FOLLOW UP
How would you solve this problem if a temporary buffer is not allowed?
這道題讓我們移除無序連結串列中的重複項,在LeetCode中有兩道類似的題是Remove Duplicates from Sorted List 移除有序連結串列中的重複項 和 Remove Duplicates from Sorted List II 移除有序連結串列中的重複項之二。這兩道都是針對有序連結串列的,而這道題是針對無序連結串列的,其實難度也不是很大。很多對於連結串列的處理的題都需要在頭結點前建立一個dummy node,目的是為了防止頭結點被移除,沒法返回新的頭結點位置。而這道題不用,因為此題讓我們刪除重複的節點,不是全刪掉,而是會保留一個,那麼不管頭結點有沒有重複項,都會保留下來。這題我們可以用雜湊表來解,思路是對於每一個節點,如果在雜湊表中存在,則刪掉,若不存在,則加入雜湊表,參見程式碼如下:
class Solution { public: ListNode *deleteDuplicates(ListNode *head) { ListNode *pre = NULL, *cur = head; int m[256] = {0}; while (cur) { if (m[cur->val] > 0) { pre->next = cur->next; } else { ++m[cur->val]; pre = cur; } cur = cur->next; } return head; } };
這道題的Follow Up讓我們不要用額外空間,即空間複雜度應為O(1),那麼我們需要兩個while迴圈來解,同時需要兩個指標,第一個指標指向一個節點,第二個指標從下一個為位置開始遍歷到連結串列末尾,遇到相同的就刪掉。以此類推直到第一個指標完成連結串列的遍歷即可刪掉所有的重複項,整體的思路和氣泡排序有些類似,但是這種方法的時間複雜度為O(n2),是一種以時間來換取空間的方法,參見程式碼如下:
class Solution { public: ListNode *deleteDuplicates(ListNode *head) { ListNode *pre = head, *cur = head; while (pre) { cur = pre->next; while (cur) { if (cur->val == pre->val) { pre->next = cur->next; } cur = cur->next; } pre = pre->next; } return head; } };