LQBv32-Python:階乘約數
阿新 • • 發佈:2021-02-07
一、需求
- 給定一個連結串列,返回連結串列開始入環的第一個節點。如果連結串列無環,則返回
null
。
輸入:head = [3,2,0,-4], pos = 1 輸出:返回索引為 1 的連結串列節點 解釋:連結串列中有一個環,其尾部連線到第二個節點。
提示:
- 連結串列中節點的數目範圍在範圍
[0, 104]
內-105<= Node.val <= 105
pos
的值為-1
或者連結串列中的一個有效索引
二、雜湊表
2.1 思路分析
- 思路參考上一篇環形連結串列:https://blog.csdn.net/Sruggle/article/details/113755887
2.2 程式碼實現
public class Solution { public ListNode detectCycle(ListNode head) { Set<ListNode> hs = new HashSet<>(); ListNode p = head; while(p != null) { if(hs.contains(p)) { return p; } hs.add(p); p = p.next; } return null; } }
2.3 複雜度分析
- 時間複雜度為O(N);
- 空間複雜度為O(N);
三、快慢指標
3.1 思路分析
- 我們知道可以通過快慢指標判斷連結串列是否有環,但該題要求返回入環的第一個節點,我們可以找到快慢指標相交時的節點,然後去找該節點和連結串列頭節點有什麼關係;
- 利用力扣題解中的一張圖來進行推導:a表示連結串列頭節點到入環節點的距離,b表示入環節點到快慢指標相交節點的距離;
- 當快慢指標相交後,快指標走過的距離為:a + n * (b + c) + b = a + (n + 1) * b + nc,其中n表示相交前快指標走過的圈數;
- 快慢指標位於同一起點,快指標每次移動是慢指標的兩倍,故快指標走過的距離是慢指標的兩倍,於是又 a + (n + 1)* b + nc = 2(a+b),得到 a = c + (n - 1) * (b + c),即從相交點到入環點的距離加上n-1倍的圈長等於
- 因此當快慢指標相交時,定義一個指標ptr從頭節點出發,它與slow一起移動,當它們相交時,就是入環節點;
3.2 程式碼實現
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head == null) {
return null;
}
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {
ListNode ptr = head;
while(ptr != slow) {
ptr = ptr.next;
slow = slow.next;
}
return ptr;
}
}
return null;
}
}
3.3 複雜度分析
- 時間複雜度為O(N),判斷快慢指標是否相交,slow指標走過的距離不會超過連結串列長度N,相交後到入環節點,走過的距離也不會超過N,故總體時間複雜度為O(N);
- 空間複雜度為O(1),指標變數消耗常數大小的額外空間;
四、學習地址
作者:LeetCode-Solution