Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
Example 1:
Input: 1->2->3->3->4->4->5 Output: 1->2->5
Example 2:
Input: 1->1->1->2->3 Output: 2->3
和之前那道 Remove Duplicates from Sorted List 不同的地方是這里要刪掉所有的重復項,由於鏈表開頭可能會有重復項,被刪掉的話頭指針會改變,而最終卻還需要返回鏈表的頭指針。所以需要定義一個新的節點,然后鏈上原鏈表,然后定義一個前驅指針和一個現指針,每當前驅指針指向新建的節點,現指針從下一個位置開始往下遍歷,遇到相同的則繼續往下,直到遇到不同項時,把前驅指針的next指向下面那個不同的元素。如果現指針遍歷的第一個元素就不相同,則把前驅指針向下移一位。代碼如下:
解法一:
class Solution { public: ListNode* deleteDuplicates(ListNode* head) { if (!head || !head->next) return head; ListNode *dummy = new ListNode(-1), *pre = dummy; dummy->next = head; while (pre->next) { ListNode *cur = pre->next; while (cur->next && cur->next->val == cur->val) { cur = cur->next; } if (cur != pre->next) pre->next = cur->next; else pre = pre->next; } return dummy->next; } };
同樣,我們也可以使用遞歸來做,首先判空,如果 head 為空,直接返回。然后判斷,若 head 之后的結點存在,且值相等,那么先進行一個 while 循環,跳過后面所有值相等的結點,到最后一個值相等的點停下。比如對於例子2來說,head 停在第三個結點1處,然后對后面一個結點調用遞歸函數,即結點2,這樣做的好處是,返回的值就完全把所有的結點1都刪掉了。若 head 之后的結點值不同,那么還是對 head 之后的結點調用遞歸函數,將返回值連到 head 的后面,這樣 head 結點還是保留下來了,因為值不同嘛,最后返回 head 即可,參見代碼如下:
解法二:
class Solution { public: ListNode* deleteDuplicates(ListNode* head) { if (!head) return head; if (head->next && head->val == head->next->val) { while (head->next && head->val == head->next->val) { head = head->next; } return deleteDuplicates(head->next); } head->next = deleteDuplicates(head->next); return head; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/82
類似題目:
Remove Duplicates from Sorted List
參考資料:
https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/