单链表的交集
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
原題
Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
?
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.
題目大意
找兩個(gè)單鏈表的交集部分。
如果沒(méi)有交集返回null。
函數(shù)操作后,單鏈表必須返回他們?cè)瓉?lái)的結(jié)構(gòu)。
假定整個(gè)鏈表中沒(méi)有環(huán)。
函數(shù)必須在O(N)時(shí)間復(fù)雜度,O(1)空間復(fù)雜度以?xún)?nèi)完成。
解題思路
先將其中一個(gè)鏈表的鏈頭按到另一個(gè)鏈表的尾部,如果他們有交集則會(huì)構(gòu)成一個(gè)環(huán),題目等價(jià)于找鏈表中的環(huán)的起始結(jié)點(diǎn)。找到后將鏈表還原。
代碼實(shí)現(xiàn)
結(jié)點(diǎn)類(lèi)
public class ListNode {int val;ListNode next;ListNode(int x) {val = x;next = null;} }?
算法實(shí)現(xiàn)類(lèi)
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA == null || headB == null) {return null;}ListNode ta; // 用于記錄headA鏈表的尾結(jié)點(diǎn)ListNode ha = headA;// 第一步、找到headA的尾結(jié)點(diǎn)while (ha.next != null) {ha = ha.next;}ta = ha; // 記錄鏈表headA的尾結(jié)點(diǎn)// 第二步、將headB接到ta后面ta.next = headB;// 第三步、判斷是否存在環(huán)// 判斷鏈表是否存在環(huán),辦法為:// 設(shè)置兩個(gè)指針(fast, slow),初始值都指向頭,slow每次前進(jìn)一步,fast每次前進(jìn)二步,// 如果鏈表存在環(huán),則fast必定先進(jìn)入環(huán),而slow后進(jìn)入環(huán),兩個(gè)指針必定相遇。// (當(dāng)然,fast先行頭到尾部為NULL,則為無(wú)環(huán)鏈表)程序如下:ListNode fast = headA; // 每次前進(jìn)一步ListNode slow = headA; // 每次前進(jìn)二步while (fast != null && fast.next != null) {fast = fast.next.next;slow = slow.next;if (fast == slow) { // 如果相遇了就退出來(lái)break;}}// 沒(méi)有環(huán)的情況if (fast == null || fast.next == null) {ta.next = null; // 解開(kāi)拼接好的鏈表return null;}// 有環(huán)的情況// 找到環(huán)的入口點(diǎn)// 當(dāng)fast若與slow相遇時(shí),slow肯定沒(méi)有走遍歷完鏈表,而fast已經(jīng)在環(huán)內(nèi)循環(huán)了n圈(1<=n)。// 假設(shè)slow走了s步,則fast走了2s步(fast步數(shù)還等于s 加上在環(huán)上多轉(zhuǎn)的n圈),設(shè)環(huán)長(zhǎng)為r,則://// 2s = s + nr// s= nr//// 設(shè)整個(gè)鏈表長(zhǎng)L,入口環(huán)與相遇點(diǎn)距離為x,起點(diǎn)到環(huán)入口點(diǎn)的距離為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)為相遇點(diǎn)到環(huán)入口點(diǎn)的距離,由此可知,從鏈表頭到環(huán)入口點(diǎn)等于(n-1)循環(huán)內(nèi)環(huán)+相遇點(diǎn)到環(huán)入口點(diǎn),// 于是我們從鏈表頭、與相遇點(diǎn)分別設(shè)一個(gè)指針,每次各走一步,兩個(gè)指針必定相遇,且相遇第一點(diǎn)為環(huán)入口點(diǎn)。slow = headA;while (slow != fast) {fast = fast.next;slow = slow.next;}ta.next = null;return slow;} }轉(zhuǎn)載于:https://my.oschina.net/u/2822116/blog/812103
總結(jié)
- 上一篇: VR與AI的激情相遇
- 下一篇: tutorial_coreos 01-0