题目
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3
解答
解法一:非递归方式
p 是游标,不断的向后遍历寻找符合条件的位置。
重点在于 pre, 如果 pre 之后有重复元素,pre 是不会移动的。
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode dummy = new ListNode(0);
ListNode pre = dummy;
ListNode p = head;
while(p != null) {
int val = p.val;
if(p.next == null || p.next.val != val) {
pre.next = p;
pre = pre.next;
} else {
while(p.next != null && p.next.val == val) {
p = p.next;
}
}
p = p.next;
}
// 清理脏结点
pre.next = null;
return dummy.next;
}
}
结果
解法二:递归方式
设置好 head 的边界条件。如果 head == null 或者 head 是链表最后一个结点,直接 return 。
如果 head 的值跟后续有重复,那么就不断循环找到第一个不再重复的结点,然后继续递归这个新节点即可。
否则,继续递归 head 后续结点。
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head == null || head.next == null) return head;
ListNode cur = head.next;
if(cur.val == head.val) {
while(cur != null && cur.val == head.val) cur = cur.next;
return deleteDuplicates(cur);
}
head.next = deleteDuplicates(cur);
return head;
}
}