Java 寻找两个链表的交点?
大多数站点都提供了这种解决方案(参见第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中。如果是,则为合并点 更新:-输入为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个元素
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(len1list2
不能在节点5
处“结束”,因为5
指向6
,依此类推,所以list2
的长度与list1
相同,算法将工作,因为d=0;明白你的意思了。你对我提出的解决方案有什么看法。我认为它不是非常非常优化的链接,但会工作:)很高兴它有帮助。请随意投票/接受。根据您的解决方案,它应该可以工作,而且实际上性能会更差,因为您不能保证在非常大的输入上HashMap O(1)的复杂性,假设列表可能非常长(例如,数十亿项),那么您发布的示例是不正确的<代码>列表2不能在节点5
处结束,因为5
链接到6
,依此类推。请参阅对我答案的评论。此外,在您的示例中:第一个列表中的节点1
:1->3
,然后第二个列表中的节点1->4
。你知道什么是链表,对吧?节点1
只能有一个next
节点。