leetcode解题: Intersection of Two Linked Lists (160)

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.

解法1: O(M + N) Time + O(1) Space

很巧妙的一个方法是如果我们将其中一个list的尾巴和另一个list的头部连接,那么就变成了求这个长list中是否有circle,如果有那么他们的交点是什么的题目。
要注意求交点的算法是:

  1. slow,fast pointer
  2. slow = head, fast = head.next
  3. 找到slow和fast相等的点
  4. 把slow挪到head, fast往下移一格
  5. 一步一步走直到slow和fast相等
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    /**
    * Definition for singly-linked list.
    * struct ListNode {
    * int val;
    * ListNode *next;
    * ListNode(int x) : val(x), next(NULL) {}
    * };
    */
    class Solution {
    public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    if (!headA || !headB) {
    return NULL;
    }
    ListNode *a = headA;
    while (a ->next) {
    a = a->next;
    }
    a->next =headB;
    ListNode* temp = circle(headA);
    a->next = NULL;
    return temp;
    }
    ListNode* circle(ListNode* head) {
    ListNode* slow = head;
    ListNode* fast = head->next;
    while (slow != fast) {
    if (!fast || !fast->next) {
    return NULL;
    }
    slow = slow->next;
    fast = fast->next->next;
    }
    slow = head;
    fast = fast->next;
    while (slow != fast) {
    slow =slow->next;
    fast =fast->next;
    }
    return slow;
    }
    };

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
* 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 tailA = headA;
while (tailA.next != null) {
tailA = tailA.next;
}
tailA.next = headB;
// A -> B
ListNode slow = headA, fast = headA.next;
while (slow != fast) {
if (fast == null || fast.next == null) {
tailA.next = null;
return null; // no cycle found
}
slow = slow.next;
fast = fast.next.next;
}
slow = headA;
fast = fast.next;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
tailA.next = null; // restore the original linked List
return slow;
}
}