删除链表中的重复值(Java中的递归)

时间:2016-11-23 07:55:03

标签: java recursion linked-list

我需要返回链表的头部,删除所有重复元素。我理解问题的逻辑,但我对使用递归感到困惑。

/*
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'。

我真的想要一些关于如何更好地理解递归的建议。

2 个答案:

答案 0 :(得分:1)

问题是你在后一种情况下“跳过”某些节点。 让我们为您示例中的节点命名,看看发生了什么:

v
1 -> 1 -> 1 -> 1
a    b    c    d

v表示您方法中head的当前引用。

如果您现在先进行检查,则比较ab,然后移除b

v
1 -> 1 -> 1
a    c    d

然后执行递归步骤,将一个节点前进到c

问题是你在后一种情况下“跳过”某些节点。 让我们为您示例中的节点命名,看看发生了什么:

v
1 -> 1 -> 1 -> 1
a    b    c    d

v表示您方法中head的当前引用。

如果您现在先进行检查,则比较ab,然后移除b

     v
1 -> 1 -> 1
a    c    d

这是你的问题。您从未将c与其左侧的值进行比较,即a / cb / 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个节点),检查它是否与下一个节点重复。你看,你错过了检查第一个节点和原来的第三个节点。

我认为你应该尝试模式调试来深入了解这一点。

顺便说一句,尝试将约定应用于您的代码。 Ĵ 希望这有帮助!