▶ 删除单链表中的重复元素。
▶ 83. 把重复元素删得只剩一个,如 1 → 1 → 2 → 3 → 3 → 3 → 4 → 5 → 5 变成 1 → 2 → 3 → 4 → 5。注意要点:第一个元素就可能重复,最后一个元素可能是重复,多个连续重复。
● 自己的代码,18 ms,记录了发生重复的第一个元素的位置,使其指向下一个不同的元素的位置。
1 class Solution 2 { 3 public: 4 ListNode* deleteDuplicates(ListNode* head) 5 { 6 if (head == nullptr || head->next == nullptr) 7 return head; 8 9 ListNode *output, *i, *j, *k; 10 for (i = head, j = head->next; i != nullptr; i = j) 11 { 12 for (; j != nullptr && i->val == j->val; j = j->next); 13 i->next = j; 14 } 15 return head; 16 } 17 };
● 大佬的代码,11 ms,逐格比较相邻两个结点,值相同则跨过后一结点。
1 class Solution 2 { 3 public: 4 ListNode* deleteDuplicates(ListNode* head) 5 { 6 for (ListNode* cur = head; cur && cur->next;) 7 { 8 if (cur->val == cur->next->val) 9 cur->next = cur->next->next; 10 else 11 cur = cur->next; 12 } 13 return head; 14 } 15 };
▶ 82. 把发生重复的元素删除得一个不剩。如 1 → 1 → 2 → 3 → 3 → 3 → 4 → 5 → 5 变成 2 → 4 。
● 自己的非递归版代码,8 ms
1 class Solution 2 { 3 public: 4 ListNode* deleteDuplicates(ListNode* head) 5 { 6 if (head == nullptr || head->next == nullptr) 7 return head; 8 for (; head != nullptr && head->next != nullptr && head->val == head->next->val;)// 去掉开头的重复结点 9 { 10 for (; head->next != nullptr && head->val == head->next->val; head = head->next); 11 head = head->next; 12 } 13 if (head == nullptr) 14 return head; 15 for (ListNode *prev = head, *cur = head->next; cur != nullptr && cur->next != nullptr; cur = prev->next) 16 { 17 if (cur->val == cur->next->val) 18 { 19 for (; cur->next != nullptr && cur->val == cur->next->val; cur->next = cur->next->next); 20 prev->next = cur->next; 21 } 22 else 23 prev = prev->next; 24 } 25 return head; 26 } 27 };
● 大佬的递归版代码,9 ms
1 class Solution 2 { 3 public: 4 ListNode* deleteDuplicates(ListNode* head) 5 { 6 if (head == nullptr || head->next == nullptr) 7 return head; 8 9 int val = head->val; 10 ListNode *p = head->next; 11 if (p->val != val) 12 { 13 head->next = deleteDuplicates(p); 14 return head; 15 } 16 else 17 { 18 for (; p && p->val == val; p = p->next); 19 return deleteDuplicates(p); 20 } 21 } 22 };