Intersection of Two Linked Lists(两个链表的交叉)

问题

Write a program to find the node at which the intersection of two singly linked lists begins.

Notice

If the two linked lists have no intersection at all, return null.
The linked lists must retain their original structure after the function returns.
You may assume there are no cycles anywhere in the entire linked structure.
Example
The following two linked lists:

Intersection of Two Linked Lists(两个链表的交叉)_第1张图片

begin to intersect at node c1.

分析

选择一个链表,从开始遍历,每次去另外一个链表中遍历查找,找到就返回。性能比较差,不再代码实现。

方法1

分析

两个链表相交,必然是从交点以后完全一样,所以差别只在相交之前。
首先算出两个链表的长度a,b,然后把长度较长的b(也可能是a),向后移动长度b-a次,这样两个链表长度就相同,同时遍历,找到相同点即可。

代码
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;      
 *     }
 * }
 */
public class Solution {
    /**
     * @param headA: the first list
     * @param headB: the second list
     * @return: a ListNode 
     */
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        // Write your code here
        int lenA=getLen(headA);
        int lenB=getLen(headB);
        while(true){
            if(headA==null||headB==null){
                break;
            }
            if(lenA>lenB){
                headA=headA.next;
                lenA--;
            }else if(lenA

方法2

分析

我们把一个链表的尾指针指向另外一个链表的头指针,这样如果有交点,他们就会形成环,重点是怎样找到第一个相交的点。
我们定义两个指针p,q,p每次走一步,q每次走两步,如果存在环,那么他们肯定相遇(操场上两个人抛步,初始位置随机,只要他们的速度不相等,肯定会相遇)。
下边我们通过数学分析来找到第一个相交的点。
假定前边的长度为n,环长为m,最后相遇在t,交点为l,p走的步数为s。

Intersection of Two Linked Lists(两个链表的交叉)_第2张图片
Intersection of Two Linked Lists(两个链表的交叉)_第3张图片

最后n=km-t,说明只要p再回到起始位置,q在t的位置继续向后走,那么他们必会相交于l,中间q可能会走多圈。

代码
* Definition for singly-linked list.
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode(int x) {
*         val = x;
*         next = null;      
*     }
* }
*/
public class Solution {
   /**
    * @param headA: the first list
    * @param headB: the second list
    * @return: a ListNode 
    */
   public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
       // Write your code here
       if(headA==null||headB==null){
           return null;
       }
       ListNode temp=headA;
       while(temp.next!=null){
           temp=temp.next;
       }
       temp.next=headB;
       ListNode p=headA;
       ListNode q=headA.next;
       while(p!=q){
           if(q==null||q.next==null){
               return null;
           }
           p=p.next;
           q=q.next.next;
       }
       p=headA;
       q=q.next;
       while(true){
           if(p==q){
               return p;
           }else{
               p=p.next;
               q=q.next;
           }
       }
   }  
}

你可能感兴趣的:(Intersection of Two Linked Lists(两个链表的交叉))