我需要返回链表的头部,删除所有重复元素。我理解问题的逻辑,但我对使用递归感到困惑。
/*
Node is defined as
class Node {
int data;
Node next;
}
*/
Node RemoveDuplicates(Node head) {
if ((head == null) || (head.next == null))
return head;
else {
RemoveDuplicates(head.next);
if (head.data==head.next.data) head.next = head.next.next;
}
return head;
}
如果我在if条件之前调用函数RemoveDuplicates(head.next);它工作正常。但是,如果我交换语句的顺序(其余部分完全相同),如:
if (head.data==head.next.data) head.next = head.next.next;
RemoveDuplicates(head.next);
代码无法正确解决“1-> 1-> 1-> 1'等测试用例。我在后一种情况下获得的输出是'1> 1'。
我真的想要一些关于如何更好地理解递归的建议。
答案 0 :(得分:1)
问题是你在后一种情况下“跳过”某些节点。 让我们为您示例中的节点命名,看看发生了什么:
v
1 -> 1 -> 1 -> 1
a b c d
v
表示您方法中head
的当前引用。
如果您现在先进行检查,则比较a
和b
,然后移除b
:
v
1 -> 1 -> 1
a c d
然后执行递归步骤,将一个节点前进到c
:
问题是你在后一种情况下“跳过”某些节点。 让我们为您示例中的节点命名,看看发生了什么:
v
1 -> 1 -> 1 -> 1
a b c d
v
表示您方法中head
的当前引用。
如果您现在先进行检查,则比较a
和b
,然后移除b
:
v
1 -> 1 -> 1
a c d
这是你的问题。您从未将c
与其左侧的值进行比较,即a
/ c
或b
/ c
。
切换线条时不会出现这个问题,因为这样你走的是另一种方式,即你自下而上(从右到左)浏览你的列表并且只在右边比较/删除(在你后面) “在行走方向上。”
答案 1 :(得分:1)
首先,您的代码只会解决列表是否有序的情况,如果数据处于随机位置,则无法删除所有重复节点,例如:1, 2, 3, 1, 1, 2, 3
其次,对于您的担忧,您可以如下所述:
案例1:
RemoveDuplicates(head.next);
if (head.data==head.next.data) head.next = head.next.next;
从列表末尾的元素开始检查,比较其数据和下一个数据(如果匹配),用下一个节点替换下一个节点。然后,跳转到上一个节点并重复。
案例2:
if (head.data==head.next.data) head.next = head.next.next;
RemoveDuplicates(head.next);
从第一个节点开始,检查它是否与下一个节点重复。如果重复,请将第3个节点替换为第2个节点。跳转到下一个节点(现在是原始的第3个节点),检查它是否与下一个节点重复。你看,你错过了检查第一个节点和原来的第三个节点。
我认为你应该尝试模式调试来深入了解这一点。
顺便说一句,尝试将约定应用于您的代码。 Ĵ 希望这有帮助!