Java 寻找两个链表的交点?

Java 寻找两个链表的交点?,java,data-structures,linked-list,Java,Data Structures,Linked List,大多数站点都提供了这种解决方案(参见第3页的方法) 1) 获取第一个列表中节点的计数,让计数为c1 2) 获取第二个列表中节点的计数,让计数为c2 3) 获取计数差d=abs(c1–c2) 4) 现在遍历从第一个节点到d个节点的较大列表,这样 从这里开始,两个列表的节点数相等 5) 然后我们可以并行遍历这两个列表,直到我们遇到 公共节点。(请注意,获取公共节点是通过比较 节点的地址) 我的理解是,如果第一个节点本身是合并节点,上述解决方案将不起作用。假设list1有5个元素,list2有3个元素

大多数站点都提供了这种解决方案(参见第3页的方法)

1) 获取第一个列表中节点的计数,让计数为c1

2) 获取第二个列表中节点的计数,让计数为c2

3) 获取计数差d=abs(c1–c2)

4) 现在遍历从第一个节点到d个节点的较大列表,这样 从这里开始,两个列表的节点数相等

5) 然后我们可以并行遍历这两个列表,直到我们遇到 公共节点。(请注意,获取公共节点是通过比较 节点的地址)

我的理解是,如果第一个节点本身是合并节点,上述解决方案将不起作用。假设list1有5个元素,list2有3个元素,其中element1是 合并点。根据上述算法,差异计数为2。首先,我们将遍历列表1中的前2个节点。从列表中的3个元素开始, 逐个遍历每个列表中的元素feom。所以我永远也得不到合并点。不是吗

我建议的解决方案:

1) 遍历列表1

2) 将每个元素内存地址(带有System.IdentityHashMap)放入基于哈希的数据结构中

3) 遍历列表2。获取每个元素的内存地址,并查看其是否存在于hashmap中。如果是,则为合并点

更新:-输入为

list1=1->3->5->6->7

list2=1->4->5


根据链接中建议的解决方案,大小差异为2。首先遍历列表1中的3,然后将
5->6->7
1->4->5
进行比较。因此,这里缺少合并点1。

好吧,这可能很简单,只要检查两个列表的根节点是否相等,如果节点相等,那就是合并点

我的理解是,如果第一个节点本身是 合并节点

您的理解不正确,前提是该方法有效。考虑到你的例子:

list1=1->2->3->4->5

list2=3->4->5
节点
3
是交叉点

差值d=5-3=2

步骤4)之后,列表1将由2转发,并将指向
3->4->5
,因此它将指向与
列表2
完全相同的节点,这将通过在步骤5)执行的第一次比较来显示。

因为这是用Java实现的,所以要比较“元素内存地址”(来自您的建议),只需比较引用即可,只有引用(“指向”)同一对象时,引用才会相等


希望这能有所帮助。

我认为这里的主要误解是关于什么是交叉点。如果我们看一下这里给出的图表和规则,清楚地说明它应该形成一个倒Y形列表,它应该意味着从交点开始的节点都应该合并,并且只通向一条路径,直到最后。大概是这样的:

[a1] -...- [aD] - [a(D+1)] -...- [a(D+n)] 
                                       \  
                                        [ab1] - [ab2] - [ab3] - ...
                                       /
                    [b1] - ... -   [bn] 
此外,您可以执行步骤3并使用更简洁的方法,如下所示:

public ListNode getIntersectionNode(ListNode a, ListNode b) {
    int len1 = getLengthOfSLL(a);
    int len2 = getLengthOfSLL(b);

    // Make a and b equidistant from the intersecting node.
    while (len1 > len2){
        a = a.next;
        len1--;
    }
    while (len1 < len2){
        b = b.next;
        len2--;
    }
    // Advance them together towards the intersection point
    while (a != b){
        a = a.next;
        b = b.next;
    }
    return a;
}
public int getLengthOfSLL(ListNode head){
    int len = 0;
    while (head != null){
        len++;
        head = head.next;
    }
    return len;
} 
公共ListNode getIntersectionNode(ListNode a、ListNode b){ int len1=getLengthOfSLL(a); int len2=getLengthOfSLL(b); //使a和b与相交节点等距。 while(len1>len2){ a=a.下一步; len1--; } while(len1查看我的更新。我的问题是,如果第一个元素正在合并怎么办point@user3198603您在更新中发布的示例无效
list2
不能在节点
5
处“结束”,因为
5
指向
6
,依此类推,所以
list2
的长度与
list1
相同,算法将工作,因为d=0;明白你的意思了。你对我提出的解决方案有什么看法。我认为它不是非常非常优化的链接,但会工作:)很高兴它有帮助。请随意投票/接受。根据您的解决方案,它应该可以工作,而且实际上性能会更差,因为您不能保证在非常大的输入上HashMap O(1)的复杂性,假设列表可能非常长(例如,数十亿项),那么您发布的示例是不正确的<代码>列表2不能在节点
5
处结束,因为
5
链接到
6
,依此类推。请参阅对我答案的评论。此外,在您的示例中:第一个列表中的节点
1
1->3
,然后第二个列表中的节点
1->4
。你知道什么是链表,对吧?节点
1
只能有一个
next
节点。