160.相交链表

编写一个程序,找到两个单链表相交的起始节点。

例如,下面的两个链表

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

在节点 c1 开始相交。

注意:

  • 如果两个链表没有交点,返回 null.
  • 在返回结果后,两个链表仍须保持原有的结构。
  • 可假定整个链表结构中没有循环。
  • 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

解法一:如果两个链长度相同的话,那么对应的一个个比下去就能找到,所以只需要把长链表变短即可。具体算法为:分别遍历两个链表,得到分别对应的长度。然后求长度的差值,把较长的那个链表向后移动这个差值的个数,然后一一比较即可。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null|| headB==null) return null;
        
        ListNode dummy1=new ListNode(0);
        ListNode dummy2=new ListNode(0);
        dummy1.next=headA;
        dummy2.next=headB;
        ListNode curA=dummy1;
        ListNode curB=dummy2;
        int length1=getLength(curA);
        int length2=getLength(curB);  
      if(length1>length2)
      {
          for(int i=0;i<length1-length2;i++)
          {
              curA=curA.next;
          }
         
      }else{
          
           for(int i=0;i<length2-length1;i++)
          {
              curB=curB.next;
          }        
      }
        while (curA != null && curB != null && curA != curB) {
            curA = curA.next;
            curB = curB.next;
        }
        return (curA != null && curB != null) ?curA : null;
    }
    private int getLength(ListNode cur)
    { 
        int k=0;
          while(cur.next!=null)
        {
           k++;
           cur=cur.next;
        }
        return k;
    }
}

解法二:

我们可以用环的思想来做,我们让两条链表分别从各自的开头开始往后遍历,当其中一条遍历到末尾时,我们跳到另一个条链表的开头继续遍历。两个指针最终会相等,而且只有两种情况,一种情况是在交点处相遇,另一种情况是在各自的末尾的空节点处相等。为什么一定会相等呢,因为两个指针走过的路程相同,是两个链表的长度之和,所以一定会相等。这个思路真的很巧妙,而且更重要的是代码写起来特别的简洁

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null|| headB==null) return null;
      
        ListNode a = headA, b = headB;
//         while(a != b)
//         {
            
//             if(a==null) a=headB;
//             else
//                  a=a.next;
//             if(b==null) b=headA;
//             else
//             b=b.next;
//         }
     
           while (a != b) {
            a = (a != null) ? a.next : headB;
            b = (b != null) ? b.next : headA;
        }
         return a;
    }
  
}

或者

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null|| headB==null) return null;
      
        ListNode a = headA, b = headB;
        while(a != b)
        {
            
            if(a==null) a=headB;
            else
                 a=a.next;
            if(b==null) b=headA;
            else
            b=b.next;
        }
     
        //    while (a != b) {
        //     a = (a != null) ? a.next : headB;
        //     b = (b != null) ? b.next : headA;
        // }
         return a;
    }
  
}

猜你喜欢

转载自blog.csdn.net/huanghuansen/article/details/83274897