标签:https 遍历 解法 基础 ext pre 复杂 head sts
题目大意:找两个链表的第一个交点。
这里先给出一些链表相交基础的说明:
对于链表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
标签:https 遍历 解法 基础 ext pre 复杂 head sts
原文地址:http://www.cnblogs.com/dalt/p/7806236.html