题目:
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5 输出: 1->2->5
示例 2:
输入: 1->1->1->2->3 输出: 2->3
这篇文章会写一个正面教材(cpp),一个反面教材(python)。
为什么这么说,因为python当时写的时候还是太稚嫩,思路还是不够简洁清晰,等到现在再回过头来看这道题,立刻就感受到了不一样的感觉。
1.pythoN代码把头部出现重复元素和头部不出现重复元素分开讨论,没有设置start节点连接原来链表头部。
2.删除过程不够简单明了。
算法过程:(C++)实现
设置start连接原来的链表头部,这样我们可以同时处理链表头部。
设置pre,cur 2个指针,pre用来指向不重复的节点,cur用来搜索重复节点部分的尾部节点。
比如1->2->2->2->3,pre指向1,cur会通过while循环找到最后一个2,于是pre->next = cur->next即可全部删除2
同时还有1->2->3的情况,这时(pre为1, cur 为2)cur == pre->next,所以pre = pre->next。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (!head || !head->next) return head;
ListNode* start = new ListNode(0);//建立新节点
start->next = head;//并且连接旧节点
ListNode* pre = start;
while (pre->next){
ListNode* cur = pre->next;
while (cur->next && cur->val == cur->next->val) cur = cur->next;//如果cur与它的下一项相同,则不断移动它
if (cur!= pre->next)pre->next = cur->next;//如果cur移动过了,说明确实存在重复项,删除即可
else pre = pre->next;//如果cur没有移动过
}
return start->next;
}
};
Python代码反面教材(警醒提示自己)
class Solution():
def deleteDuplicates(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
i = head
if not i:
return head
j = i.next
if not j:
return head
while j and i and j.val == i.val:#先删除头部相同的节点
j = j.next
if not j:
return None
if j.val != i.val:
i = j
j = j.next
continue
head = i#确定新头部的节点
while i.next:
if not i.next.next:
return head
j = i.next
if j.val == j.next.val:
while j and j.next and j.val == j.next.val:
j = j.next
if j.next and j.next.next and j.next.val == j.next.next.val and j.next.val != j.val:
j = j.next
continue
i.next = j.next#执行删除操作
else:
i = i.next
return head