160. Intersection of Two Linked Lists

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

 

For example, the following two linked lists:

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

begin to intersect at node c1.

 

Notes:

    • 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.
    • Your code should preferably run in O(n) time and use only O(1) memory.

 

先查找两个链表长度,长的链表先跳过差的长度,然后一起走,当相遇时即找到该元素。

更好些的算法:

  • Two pointer solution (O(n+m) running time, O(1) memory):
    • Maintain two pointers pA and pB initialized at the head of A and B, respectively. Then let them both traverse through the lists, one node at a time.
    • When pA reaches the end of a list, then redirect it to the head of B (yes, B, that's right.); similarly when pB reaches the end of a list, redirect it the head of A.
    • If at any point pA meets pB, then pA/pB is the intersection node.
    • To see why the above trick would work, consider the following two lists: A = {1,3,5,7,9,11} and B = {2,4,9,11}, which are intersected at node '9'. Since B.length (=4) < A.length (=6), pB would reach the end of the merged list first, because pB traverses exactly 2 nodes less than pA does. By redirecting pB to head A, and pA to head B, we now ask pB to travel exactly 2 more nodes than pA would. So in the second iteration, they are guaranteed to reach the intersection node at the same time.
    • If two lists have intersection, then their last nodes must be the same one. So when pA/pB reaches the end of a list, record the last element of A/B respectively. If the two last elements are not the same one, then the two lists have no intersections.

/**
* 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) {
    int lengthA = getLength(headA);
    int lengthB = getLength(headB);
    if (lengthA > lengthB) {
      headA = jump(headA, lengthA - lengthB);
    } else {
      headB = jump(headB, lengthB - lengthA);
    }
    while(headA != headB && headA != null) {
      headA = headA.next;
      headB = headB.next;
    }
    return headA;
  }

  public ListNode jump(ListNode head, int steps) {
    while (head != null && steps > 0) {
      head = head.next;
      steps --;
    }
    return head;
  }

  public int getLength(ListNode head) {
    int length = 0;
    while (head != null) {
      length ++;
      head= head.next;
    }
    return length;
  }
}

 

posted on 2015-04-14 11:25  shini  阅读(102)  评论(0编辑  收藏  举报

导航