2 minutes
Week1017_algorithm
ARTS - Algorithm
补 10月29日
82. 删除排序链表中的重复元素 II
题目
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5 输出: 1->2->5 示例 2:
输入: 1->1->1->2->3 输出: 2->3
分析
此题和 [83. 删除排序链表中的重复元素](https://leetcode-cn.com/problems/remove- duplicates-from-sorted-list/description/) 相似,属于在这道题的基础上增加了一个难度,不仅是重复的变成不重复的,还要把重复过的元素都删掉。
初始的想法是,首先把遇到的和next相等的元素,把next 删掉,把当前的标记,第二次把标记过的删除,但是这样存在问题,
- 标记的方式,如果设置当前元素的值为某一个数,如果元素中存在这个,就造成不准确;
- 如果存在连续重复的,标记了一个就无法删除掉全部的重复数据。 所以这种方法是不可行的,
还有一个方法,是双向循环链表结构,这样的话可以让前驱直接指向后继的后继,就一次删除了当前的和当前的后继, 但是存在连续重复的问题,需要把重复元素保存起来。
代码如下:
public static ListNode deleteDuplicates(ListNode head) {
// 1. 记录重复值, 2.删除重复值, 3.从第二个开始
ListNode node = head;
ListNode prev = new ListNode(head.val - 1);
ListNode first = prev;
int duplicate = prev.val;
prev.next = node;
while (node != null && node.next != null) {
// 如果当前和重复的相等,就把当前删掉
if (node.val == duplicate) {
prev.next = node.next;
node = node.next;
} else {
// 当前不重复,就判断和下一个重复
if (node.val == node.next.val) {
duplicate = node.val;
// 向前推进两个
prev.next = node.next.next;
node = node.next.next;
} else {
// 不重复
prev = node;
node = node.next;
}
}
}
return first.next;
}
这个看似正确,但是如果head.val = Integer.MIN_VALUE d 的话,程序会报错的,所以不是正确答案。
代码
参考了答案后,代码如下:
public static ListNode deleteDuplicates(ListNode head) {
ListNode tail = new ListNode(0);
tail.next = head;
head = tail;
boolean flag = false;
for (ListNode node = head.next; node != null && node.next != null; node = node.next) {
if (!flag && node.val == node.next.val) {
flag = true;
continue;
}
if (flag && node.val != node.next.val) {
flag = false;
tail.next = node.next;
continue;
}
if (!flag) {
tail = node;
}
}
if (flag) {
tail.next = null;
}
return head.next;
}
Read other posts