java从排序的链表中删除重复的节点。为什么我的输出是错误的?
给定一个已排序的链表,删除所有具有重复编号的节点,只留下与原始列表不同的编号
例如:
给定
1->2->3->3->4->4->5->null
,返回1->2->5->null
给定
1->1->1->2->3->null
,返回2->3->null
问题:
- 给定
1->1->1->2->3->null
,我下面的解决方案return 3->null
有人能告诉我为什么吗
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param ListNode head is the head of the linked list
* @return: ListNode head of the linked list
*/
public static ListNode deleteDuplicates(ListNode head) {
// write your code here
if(head == null || head.next == null) return head;
ListNode post = head.next;
ListNode curr = head;
ListNode dummy = new ListNode(head.val-1); // make sure dummy node value is different from the head
dummy.next = head;
ListNode prev = dummy;
while(post != null) {
//System.out.println("prev.val = " + prev.val + ", curr.val = " + curr.val + ", post.val = " + post.val + ", prev.next.val = " + prev.next.val);
//System.out.println("prev.next.val = " + prev.next.val + ", curr.next.val = " + curr.next.val);
if(prev.next.val == curr.val && prev.next.val == post.val) {
curr = curr.next;
post = post.next;
}
else if(prev.next.val == curr.val && prev.next.val != post.val) {
curr = curr.next;
post = post.next;
prev.next = curr;
}
else {
prev = prev.next;
curr = curr.next;
post = post.next;
}
}
return dummy.next;
}
}
# 1 楼答案
在不改变程序功能的情况下, 可以将
while
循环转换为更可读的形式:这相当于您的实际代码。 我会根据这个版本来解释, 因为我觉得这更容易阅读和推理
让我们观察几件事:
在开头,
prev.next
指向curr
。 所以prev.next.val
等于curr.val
。 而且,post
比curr
领先一步curr
与post
一起移动。curr
和post
在if
条件内没有改变, 作为循环的最后一步, 他们都向前推进一个位置考虑到输入1、1、1、2、3和上述观察结果:
外部
if
条件将为假,直到post
达到2curr
落后一步,所以它指向2之前的1prev
没有移动,所以prev.next
仍然指向第一个1所以在这一点上,
prev.next.val
等于curr.val
(都是1), 但它不等于post.val
,也就是2。 所以我们进入了外部的if作为
prev.next.val == curr.val
,我们也输入内部if
, 并设置prev.next = curr.next
。 请记住,循环的最后一步是将curr
前进到curr.next
。 所以prev.next
将指向curr
在下一次迭代中,我们在3处有
post
,在2处有curr
,并且prev.next
指向curr
。因此,我们输入另一个if
,然后输入内部if
,将prev.next
设置为curr.next
,即3这就是结局}}之后,
而实现将错误地返回
prev
从未移动过,它呆在原地,也就是{prev.next
指向3,我们返回的是错误的。 请注意,如果输入较长,例如1、1、1、2、3、4、5、6, 同样的行为还会继续,prev.next
在{6 -> null
。 算法被破坏了考虑这种替代算法:
head
作为下一个节点(正如您已经做的那样)next.val
和next.next.val
next.val
的副本next
和next.next
(设置在next.next.next
旁边)val
的节点dummy.next
像这样: