【问题标题】:Finding Intersection point of two linked list?寻找两个链表的交点?
【发布时间】:2014-06-12 03:08:06
【问题描述】:

大多数网站都提供此解决方案(请参阅 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 elementin 列表开始, 逐个遍历每个列表的元素feom。所以我永远不会得到合并点。不是吗?

我提出的解决方案:

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。

【问题讨论】:

  • 您发布的示例不正确。 list2 不能在节点5结束,因为5 链接到6 等等。请参阅对我的回答的评论。
  • 此外,在您的示例中:节点11 -> 3 在第一个列表中,然后1 -> 4 在第二个列表中。你确实知道链表是​​什么,对吧?节点1 只能有一个next 节点。

标签: java data-structures linked-list


【解决方案1】:

我认为这里的主要误解是关于什么是交点。如果我们查看那里给出的图表并且规则清楚地说明它应该形成一个倒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;
} 

【讨论】:

    【解决方案2】:

    如果第一个节点本身是,我的理解是上述解决方案将不起作用 合并节点

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

    list1 = 1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 5

    list2 = 3 -&gt; 4 -&gt; 5 和节点3 是交集。

    差 d = 5 - 3 = 2,

    步骤 4) list1 将被转发 2 并指向 3 -&gt; 4 -&gt; 5,因此它将指向与 list2 完全相同的节点,这将通过第一次比较揭示第 5 步)

    因为您在 Java 中实现了这一点,所以要比较“元素内存地址”(来自您的提案),您只需比较引用,只有当它们引用(“指向”)同一个对象时才会给您相等性。

    希望对您有所帮助。

    【讨论】:

    • 查看我的更新。我的问题是如果第一个元素是合并点怎么办
    • @user3198603 您在更新中发布的示例无效。 list2 不能在节点5 处“结束”,因为5 指向6,以此类推,所以list2 的长度与list1 相同,并且算法将起作用,因为d = 0 ;
    • 明白你的意思。另外,您对我提出的解决方案有何看法。我认为它不像链接中给出的那样优化,但会起作用:)
    • 很高兴它有帮助。随意赞成/接受。根据您的解决方案,它应该可以工作,实际上性能会更差,因为您不能保证非常大的输入的 HashMap O(1) 复杂性,假设列表可能非常长(例如,数十亿个项目)
    【解决方案3】:

    嗯,这可以像检查两个列表的根节点是否相等一样简单,如果节点相等,那就是你的合并点。

    【讨论】:

      猜你喜欢
      • 2019-09-12
      • 2021-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多