Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:node
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.算法
找兩個單鏈表的交集部分。
若是沒有交集返回null。
函數操做後,單鏈表必須返回他們原來的結構。
假定整個鏈表中沒有環。
函數必須在O(N)時間複雜度,O(1)空間複雜度之內完成。函數
先將其中一個鏈表的鏈頭按到另外一個鏈表的尾部,若是他們有交集則會構成一個環,題目等價於找鏈表中的環的起始結點。找到後將鏈表還原。spa
結點類.net
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 ta; // 用於記錄headA鏈表的尾結點 ListNode ha = headA; // 第一步、找到headA的尾結點 while (ha.next != null) { ha = ha.next; } ta = ha; // 記錄鏈表headA的尾結點 // 第二步、將headB接到ta後面 ta.next = headB; // 第三步、判斷是否存在環 // 判斷鏈表是否存在環,辦法爲: // 設置兩個指針(fast, slow),初始值都指向頭,slow每次前進一步,fast每次前進二步, // 若是鏈表存在環,則fast一定先進入環,而slow後進入環,兩個指針一定相遇。 // (固然,fast先行頭到尾部爲NULL,則爲無環鏈表)程序以下: ListNode fast = headA; // 每次前進一步 ListNode slow = headA; // 每次前進二步 while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) { // 若是相遇了就退出來 break; } } // 沒有環的狀況 if (fast == null || fast.next == null) { ta.next = null; // 解開拼接好的鏈表 return null; } // 有環的狀況 // 找到環的入口點 // 當fast若與slow相遇時,slow確定沒有走遍歷完鏈表,而fast已經在環內循環了n圈(1<=n)。 // 假設slow走了s步,則fast走了2s步(fast步數還等於s 加上在環上多轉的n圈),設環長爲r,則: // // 2s = s + nr // s= nr // // 設整個鏈表長L,入口環與相遇點距離爲x,起點到環入口點的距離爲a。 // a + x = nr // a + x = (n – 1)r +r = (n-1)r + L - a // a = (n-1)r + (L – a – x) // // (L – a – x)爲相遇點到環入口點的距離,由此可知,從鏈表頭到環入口點等於(n-1)循環內環+相遇點到環入口點, // 因而咱們從鏈表頭、與相遇點分別設一個指針,每次各走一步,兩個指針一定相遇,且相遇第一點爲環入口點。 slow = headA; while (slow != fast) { fast = fast.next; slow = slow.next; } ta.next = null; return slow; } }