Time:2019/4/8
Title: Linked List Cycle II
Difficulty: medium
Author:小鹿
javascript
Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.java
To represent a cycle in the given linked list, we use an integer pos
which represents the position (0-indexed) in the linked list where tail connects to. If pos
is -1
, then there is no cycle in the linked list.node
Note: Do not modify the linked list.git
給定一個鏈表,返回鏈表開始入環的第一個節點。 若是鏈表無環,則返回 null
。github
爲了表示給定鏈表中的環,咱們使用整數 pos
來表示鏈表尾鏈接到鏈表中的位置(索引從 0 開始)。 若是 pos
是 -1
,則在該鏈表中沒有環。算法
說明:不容許修改給定的鏈表。編程
Example 1:bash
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.
複製代碼
Example 2:ui
Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.
複製代碼
Example 3:this
Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.
複製代碼
Follow up: Can you solve it without using extra space?
題目要求返回單鏈表中存在循環鏈表的位置。
一、首先,先判斷該單鏈表是否存在循環鏈表?用兩個快慢指針(fast、slow)分別指向鏈表的頭部,fast 每次移動兩步,slow 每次移動一步,fast 移動的步數是 slow 的兩倍。
二、當 slow 與 fast 發生重合的時候,則存在鏈表。(slow 遍歷完單鏈表一遍,fast 遍歷了單鏈表兩遍,2 倍的關係,若是 pos = 0 時,正好在頭結點重合)。
三、若是 pos > 0 的時候。也就是說單鏈表中存在環,slow 到與 fast 指針重合的地方走過的路徑爲 n,fast 走過的路徑是 slow 的兩倍也就是 2n 。若是此時讓 fast 每次走一步,走 n 步以後還會回到重合點。
四、那麼怎麼知道環接入的位置呢?這裏稍微用的到點數學知識,看下圖:
當 fast 指針和 slow 指針重合時,咱們在聲明一個 q 指針來計算到環結點的距離,由於 fast 改成每次移動一步,且 q 也要移動一步,fast 與 q 重合的地方就是環的接入點。(由於 slow 走過的路徑和 fast 走過的路徑相同,其中不重合的地方就是接入點)
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
/** * @param {ListNode} head * @return {ListNode} */
var detectCycle = function(head) {
//判斷頭結點是否爲 null
if(head == null || head.next == null){
return null;
}
let fast = head;
let slow = head;
while(fast !== null && fast.next !== null){
fast = fast.next.next;
slow = slow.next;
//查找接入點
if(fast == slow){
slow = head;
while(slow !== fast){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
return null;
};
複製代碼
歡迎一塊兒加入到 LeetCode 開源 Github 倉庫,能夠向 me 提交您其餘語言的代碼。在倉庫上堅持和小夥伴們一塊兒打卡,共同完善咱們的開源小倉庫! Github:https://github.com/luxiangqiang/JS-LeetCode 歡迎關注我我的公衆號:「一個不甘平凡的碼農」,記錄了本身一路自學編程的故事。