# 删除排序链表中的重复元素 ||
题目要求:
给定一个已排序的链表的头 head
, 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]
示例 2:
输入:head = [1,1,1,2,3]
输出:[2,3]
提示:
- 链表中节点数目在范围
[0, 300]
内 -100 <= Node.val <= 100
- 题目数据保证链表已经按升序 排列
# 方法 1: 递归
递归函数负责返回:从当前节点 (我) 开始,完成去重的链表
- 若我与 next 重复,一直找到下一个不重复的节点,以它的返回结果为准
- 若我与 next 不重复,返回我,同时更新 next
deleteDuplicates(ListNode p = 1) | |
{ | |
deleteDuplicates(ListNode p = 1) | |
{ | |
deleteDuplicates(ListNode p = 2) | |
{ | |
deleteDuplicates(ListNode p = 3) | |
{ | |
deleteDuplicates(ListNode p = 3) | |
{ | |
// 只剩一个节点,返回 | |
} | |
} | |
} | |
} | |
} |
代码:
public ListNode deleteDuplicates(ListNode head) { | |
if(head == null || head.next == null) | |
{ | |
return head; | |
} | |
if(head.val == head.next.val) | |
{ | |
ListNode x = head.next.next; | |
while(x != null && x.val == head.val) | |
{ | |
x = x.next; | |
} | |
return deleteDuplicates(x); | |
}else | |
{ | |
head.next = deleteDuplicates(head.next); | |
return head; | |
} | |
} |
# 方法 2:非递归
p1 是待删除的上一个节点,每次循环对比 p2,p3 的值
- 如果 p2 与 p3 的值重复,那么 p3 继续后移,直到找到与 p2 不重复的节点,p1 指向 p3 完成删除
- 如果 p2 与 p3 的值不重复,p1,p2,p3 向后平移一位,继续上面的操作
- p2 或 p3 为 null 退出循环
p1 p2 p3 | |
S,1,1,1,2,3,nu11 | |
p1 p2 p3 | |
S,1,1,1,2,3,nu11 | |
p1 p2 p3 | |
S,1,1,1,2,3,nu11 | |
p1 p3 | |
S,2,3,nu11 | |
p1 p2 p3 | |
S,2,3,nu11 | |
p1 p2 p3 | |
S,2,3,nu11 |
代码:
public ListNode deleteDuplicates(ListNode head) { | |
if(head == null || head.next == null) | |
{ | |
return head; | |
} | |
ListNode s = new ListNode(-1, head); | |
ListNode p1 = s; | |
ListNode p2, p3; | |
while((p2 = p1.next) != null && (p3 = p2.next) != null) | |
{ | |
if(p2.val == p3.val) | |
{ | |
while((p3 = p3.next) != null && p3.val == p2.val) | |
{ | |
} | |
p1.next = p3; | |
}else | |
{ | |
p1 = p1.next; | |
} | |
} | |
return s.next; | |
} |