找到两个链表的交点?

时间:2014-04-26 10:12:35

标签: java data-structures linked-list

大多数网站都提供此解决方案(请参阅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 -> 71 -> 4 -> 5进行比较。所以在这里错过了合并点1。

3 个答案:

答案 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;
}