题目:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
输入: 1->1->2
输出: 1->2
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null) return head;
ListNode pre = head, cur = head.next;
while (cur != null) {
while (cur != null && cur.val == pre.val) cur = cur.next;
pre.next = cur;
pre = cur;
if (cur == null) return head;
else cur = cur.next;
}
return head;
}
题目:给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
输入: 1->2->3->3->4->4->5
输出: 1->2->5
输入: 1->1->1->2->3
输出: 2->3
方法1. 递归
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null) return head;
ListNode q = head.next;
if (head.val == q.val) {
// 类似于:1 1 1 2 2 3 这种情况,也就是head也要删除
while (q != null && q.val == head.val) q = q.next;
head = deleteDuplicates(q);
} else {
// 1 2 2 3 这种情况,head不删除
head.next = deleteDuplicates(q);
}
return head;
}
方法2. 迭代
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null) return head;
ListNode dummy = new ListNode(-1); // 冗余节点
dummy.next = head;
ListNode pre = dummy, cur = head.next; // pre是当前已去重链表的尾,cur是工作节点
int flag = head.val; // flag是cur需要比较是否相等的值
while (cur != null) {
while (cur != null && cur.val == flag) cur = cur.next;
if (pre.next.next == cur) {
//flag和cur是相邻的,说明没有发现重复,pre前进
pre = pre.next;
} else {
// 发现重复,把pre到cur中间的链表去掉
pre.next = cur;
}
if (cur != null) {
// cur没到链表尾,更新下一次要比较的值和工作指针
flag = cur.val;
cur = cur.next;
}
}
return dummy.next;
}