Leetcode:Intersection of Two Linked Lists

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode:Intersection of Two Linked Lists相关的知识,希望对你有一定的参考价值。

  题目大意:找两个链表的第一个交点。


 这里先给出一些链表相交基础的说明:

  对于链表X,用X[i]表示链表X的第i个元素,L(X)表示X的长度。

  性质1:如果X[i]等于Y[j],那么可以推出X[i+1]等于Y[j+1]。

  性质2:如果X[i]等于Y[j]且X[i-1]不等于Y[j-1],那么X和Y的第一个交点为X[i]。

  性质3:如果X[i]=Y[j],那么L(X)-i=L(Y)-j。

  这个题目有一个非常有趣的解法(参考自https://discuss.leetcode.com/topic/28067/java-solution-without-knowing-the-difference-in-len?page=1)。直接上代码:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode a = headA;
        ListNode b = headB;
        while(a != b)
        {
            a = a == null ? headB : a.next;
            b = b == null ? headA : b.next;
        }
        return a;
    }
}

  这里通过两个指针a,b分别遍历链表headA与headB,在a遍历完headA所代表的链表后则继续遍历headB,同样b遍历完headB代表的链表后则继续遍历headA。

  先说明while循环必定会终止。假设n为headA的链表长度,m为headB的链表长度,那么在第n+m次while循环时,a和b将分别抵达headB和headA的尾部,即均为null。因此我们能保证while最多循环不超过n+m次。

  在知道了循环在n+m次执行必定终止,那么很容易分析出时间复杂度为O(n+m),同样由于只使用了两个指针,因此空间复杂度为O(1)。

  最后说明算法的正确性,即当while循环退出时,a和b代表headA和headB二者第一个相交的结点。可以分2种情况进行讨论:

  n等于m时:由于n等于m,因此我们能保证第一个相交的结点必定能在前面n步内发现(因为第n步a和b同时为null)。当第i次while循环退出时,显然满足headA[i]=headB[i]且headA[i-1]!=headB[i-1],故a=headA[i]为第一个交点。

  n不等于m时:记s=max(n,m),我们能保证在前面s次while循环内不可能满足a==b(若存在i<s满足headA[i]=headB[i],由性质3可以推出L(headA)=L(headB))。因此while会在a和b分别遍历headB和headA的过程中退出。当从while循环退出时,由于性质2的前提被满足,故得到的是第一个交点。

以上是关于Leetcode:Intersection of Two Linked Lists的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode:Intersection of Two Linked Lists

[LeetCode] Intersection of Two Arrays II

LeetCode:Intersection of Two Arrays II

[LeetCode] Intersection of Two Arrays 两个数组

Python 解LeetCode:Intersection of Two Arrays

[LeetCode] Intersection of Two Arrays