大多数网站都提供此解决方案(请参阅http://www.geeksforgeeks.org/write-a-function-to-get-the-intersection-point-of-two-linked-lists/上的方法3)
1)获取第一个列表中节点的计数,让count为c1。
2)获取第二个列表中节点的计数,让count为c2。
3)得到计数差d = abs(c1-c2)
4)现在从第一个节点到d节点遍历更大的列表 从这里开始,两个列表都没有相同的节点。
5)然后我们可以并行遍历这两个列表,直到我们遇到 一个公共节点。 (请注意,通过比较来获取公共节点 节点的地址)
我的理解是,如果第一个节点本身正在合并节点,那么解决方案就无法工作。假设list1有5个元素,list2有3个元素,其中element1是 合并点。如上所述,差值计数为2.因此,首先我们将遍历list1中的前2个节点。从3个元素列表开始, 遍历元素每个列表逐个列出。所以我永远不会得到融合点。不是吗?
我建议的解决方案:
1)遍历list1。
2)将每个元素的内存地址(使用System.identitityHashMap)放在基于哈希的数据结构中
3)遍历list2.获取每个元素的内存地址,看它是否存在于hashmap中。如果是,那就是合并点。
更新: - 输入
list1 = 1 -> 3 -> 5 -> 6 -> 7
list2 = 1 -> 4 -> 5
根据链接中建议的解决方案大小为2.首先在list1中遍历3,然后将5 -> 6 -> 7
与1 -> 4 -> 5
进行比较。所以在这里错过了合并点1。
答案 0 :(得分:1)
我的理解是上面的解决方案,如果第一个节点本身是 合并节点
如果方法有效,您的理解是不正确的。考虑你的例子:
list1 = 1 -> 2 -> 3 -> 4 -> 5
list2 = 3 -> 4 -> 5
和节点3
是交集。
差异d = 5 - 3 = 2,
在第4步之后之后,list1将被转发2并指向3 -> 4 -> 5
,因此它将指向与list2
完全相同的节点,这将显示为第一次比较在步骤5)。
由于您在Java中实现了这一点,为了比较“元素内存地址”(来自您的提议),您只需比较引用,只有当它们引用(“指向”)相同的对象时才会给出相等性。
希望有所帮助。
答案 1 :(得分:0)
嗯,这可能就像检查两个列表的根节点是否相等一样简单,如果节点相等,那就是你的合并点。
答案 2 :(得分:0)
我认为这里的主要误解是关于交点。如果我们查看那里给出的图,并且规则明确指出它应该形成一个倒置的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;
}