Leetcode OJ: Remove Duplicates from Sorted List I/II
对排序数组中重复元素的删除操作,这里分两种情况,一种是重复的元素合并,另一种是重复元素的删除。先从简单的做起:合并
Given a sorted linked list, delete all duplicates such that each element appear only once.
For example,
Given1->1->2
, return1->2
.
Given1->1->2->3->3
, return1->2->3
.
这个就跟数组中重复元素合并差不多,只需要考虑当前节点与下一个节点的关系。
只需要判断当前节点与下一个节点是否相等,不等则把前节点接上目标链表中,这种不等除了值以外,还包括下一个节点为空的情况。
为了操作方便,代码中用到一个虚构的链表头用以辅助操作,代码如下:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *deleteDuplicates(ListNode *head) { 12 ListNode vhead(0); 13 vhead.next = head; 14 ListNode* pre = &vhead; 15 ListNode* p = pre->next; 16 while (p != NULL) { 17 if (p->next == NULL || p->next->val != p->val) { 18 pre->next = p; 19 pre = p; 20 } 21 p = p->next; 22 } 23 return vhead.next; 24 } 25 };
那删除重复元素又有什么区别呢?
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given1->2->3->3->4->4->5
, return1->2->5
.
Given1->1->1->2->3
, return2->3
.
我们需要把重复的删掉。
首先要记录上次删掉的顶点deleted,初始为NULL。
当遇到当前节点与下一节点重复时,我们在跳过前还需要把重复的节点记录到deleted中。
当前节点与下一节点不重复且deleted与当前节点值不重复,那么就把当前节点与目标链表接上。
到最后一个节点时,也作同样判断,不同的是判断到有重复时,需要在目标链表结尾处补上一个NULL。
以上的条件还是需要仔细想想的,LZ表示考虑了很久才化简到个人认为比较容易理解的条件了。看代码:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *deleteDuplicates(ListNode *head) { 12 ListNode vhead(0); 13 vhead.next = head; 14 ListNode* deleted = NULL; 15 ListNode* pre = &vhead; 16 ListNode* p = pre->next; 17 while (p != NULL) { 18 if (p->next != NULL) { 19 if (p->val == p->next->val) { 20 deleted = p; 21 } else { 22 if (deleted == NULL || p->val != deleted->val) { 23 pre->next = p; 24 pre = p; 25 } 26 } 27 } else { 28 if (deleted == NULL || p->val != deleted->val) { 29 pre->next = p; 30 } else { 31 pre->next = NULL; 32 } 33 } 34 p = p->next; 35 } 36 return vhead.next; 37 } 38 };