|
| 1 | +--- |
| 2 | +title: 142.Ring linkedII.md |
| 3 | +date: '2024.01.01 0:00' |
| 4 | +tags: |
| 5 | + - - Python |
| 6 | + - - answer |
| 7 | +abbrlink: e2c9cca9 |
| 8 | +--- |
| 9 | + |
| 10 | +[//]: # () |
| 11 | +[//]: # (# topic:) |
| 12 | + |
| 13 | +[//]: # (<p>Given the head node of a linked list <code>head</code> ,The first node returning to the linked list to start the ring。 <em>If the linked linked linked,Then return <code>null</code>。</em></p>) |
| 14 | + |
| 15 | +[//]: # () |
| 16 | +[//]: # (<p>If there is a node in the linked list,Can be tracked continuously <code>next</code> The pointer arrives again,Then there is a ring in the linked list。 To show the ring in the linked list,Internal use of the evaluation system <code>pos</code> Let's represent the position connected to the linked list to the position of the linked list(<strong>Index 0 start</strong>)。if <code>pos</code> yes <code>-1</code>,There is no ring in this linked list。<strong>Notice:<code>pos</code> Pass the non -as a parameter</strong>,仅仅yes为了标识Linked的实际情况。</p>) |
| 17 | + |
| 18 | +[//]: # () |
| 19 | +[//]: # (<p><strong>Modification is not allowed </strong>Linked。</p>) |
| 20 | + |
| 21 | +[//]: # () |
| 22 | +[//]: # (<ul> ) |
| 23 | + |
| 24 | +[//]: # (</ul>) |
| 25 | + |
| 26 | +[//]: # () |
| 27 | +[//]: # (<p> </p>) |
| 28 | + |
| 29 | +[//]: # () |
| 30 | +[//]: # (<p><strong>Exemplary example 1:</strong></p>) |
| 31 | + |
| 32 | +[//]: # () |
| 33 | +[//]: # (<p><img src="https://assets.leetcode.com/uploads/2018/12/07/circularlinkedlist.png" /></p>) |
| 34 | + |
| 35 | +[//]: # () |
| 36 | +[//]: # (<pre>) |
| 37 | + |
| 38 | +[//]: # (<strong>enter:</strong>head = [3,2,0,-4], pos = 1) |
| 39 | + |
| 40 | +[//]: # (<strong>Output:</strong>Back indexes 1 的Linked节点) |
| 41 | + |
| 42 | +[//]: # (<strong>explain:</strong>Linked中have一indivual环,The tail is connected to the second node。) |
| 43 | + |
| 44 | +[//]: # (</pre>) |
| 45 | + |
| 46 | +[//]: # () |
| 47 | +[//]: # (<p><strong>Exemplary example 2:</strong></p>) |
| 48 | + |
| 49 | +[//]: # () |
| 50 | +[//]: # (<p><img alt="" src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/07/circularlinkedlist_test2.png" /></p>) |
| 51 | + |
| 52 | +[//]: # () |
| 53 | +[//]: # (<pre>) |
| 54 | + |
| 55 | +[//]: # (<strong>enter:</strong>head = [1,2], pos = 0) |
| 56 | + |
| 57 | +[//]: # (<strong>Output:</strong>Back indexes 0 的Linked节点) |
| 58 | + |
| 59 | +[//]: # (<strong>explain:</strong>Linked中have一indivual环,The tail is connected to the first node。) |
| 60 | + |
| 61 | +[//]: # (</pre>) |
| 62 | + |
| 63 | +[//]: # () |
| 64 | +[//]: # (<p><strong>Exemplary example 3:</strong></p>) |
| 65 | + |
| 66 | +[//]: # () |
| 67 | +[//]: # (<p><img alt="" src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/07/circularlinkedlist_test3.png" /></p>) |
| 68 | + |
| 69 | +[//]: # () |
| 70 | +[//]: # (<pre>) |
| 71 | + |
| 72 | +[//]: # (<strong>enter:</strong>head = [1], pos = -1) |
| 73 | + |
| 74 | +[//]: # (<strong>Output:</strong>return null) |
| 75 | + |
| 76 | +[//]: # (<strong>explain:</strong>Linked中没have环。) |
| 77 | + |
| 78 | +[//]: # (</pre>) |
| 79 | + |
| 80 | +[//]: # () |
| 81 | +[//]: # (<p> </p>) |
| 82 | + |
| 83 | +[//]: # () |
| 84 | +[//]: # (<p><strong>hint:</strong></p>) |
| 85 | + |
| 86 | +[//]: # () |
| 87 | +[//]: # (<ul> ) |
| 88 | + |
| 89 | +[//]: # ( <li>Linked中节点的数目范围在范围 <code>[0, 10<sup>4</sup>]</code> Inside</li> ) |
| 90 | + |
| 91 | +[//]: # ( <li><code>-10<sup>5</sup> <= Node.val <= 10<sup>5</sup></code></li> ) |
| 92 | + |
| 93 | +[//]: # ( <li><code>pos</code> Value <code>-1</code> 或者Linked中的一indivualhave效索引</li> ) |
| 94 | + |
| 95 | +[//]: # (</ul>) |
| 96 | + |
| 97 | +[142.Ring listII.md](https://leetcode.cn/problems/linked-list-cycle-ii/) |
| 98 | + |
| 99 | +# Thought: |
| 100 | +### Problem -solving: |
| 101 | +这类Linkedtopic一般都yes使用双pointer法解决的,For example, looking for distance tail K Node、Find a ring entrance、Find the entrance of the public tail, etc.。 |
| 102 | +### Algorithm: |
| 103 | +1. Double pointer met for the first time: Set two pointers fast,slow 指向Linked头部 head,fast Walk per round 2 step,slow Walk per round 1 step; |
| 104 | + |
| 105 | + a. First result: fast pointer走过Linked末端,说明Linked无环,直接return null; |
| 106 | + |
| 107 | + .TIPS: If there is a ring,Two pointers will definitely meet。Because every time I go 1 wheel,fast and slow Pitch +1,fast The event will catch up slow; |
| 108 | + b. Second result: whenfast == slowhour, Two pointers in the ring First encounter 。下面分析此hourfast and slowPassing step数关系 : |
| 109 | + |
| 110 | + .设Linked共have a+b Node,in Linked头部到Linked入口 have a Node(不计Linked入口节点), Linked环 have b Node(这里需要Notice,a and b yes未知数,例如图解上Linked a=4 , b=5);Set two pointers分别走了 f,s step,则have: |
| 111 | + a. fast 走的step数yesslowstep数的 2 Double,Right now f=2s;(Analyze: fast Walk per round 2 step) |
| 112 | + b.fast Compare slowGo more n Length of a ring,Right now f=s+nb;( Analyze: Double pointers have gone through a step,然后在环Inside绕圈直到重合,重合hour fast Compare slow Go 环的长度整数Double ); |
| 113 | + .The above two types are reduced:f=2nb,s=nb,Right nowfastandslow The pointer left separately 2n,n indivual Circumference of the ring (Notice: n yes未知数,不同Linked的情况不同)。 |
| 114 | + |
| 115 | +<!--more--> |
| 116 | + |
| 117 | +2. Current situation analysis: |
| 118 | + |
| 119 | + .if让pointer从Linked头部一直向前走并统计step数k,那么所have 走到Linked入口节点hour的step数 yes:k=a+nb(Leave first a step到入口节点,Over time 1 Ring( b step)I will go to the entrance node again)。 |
| 120 | + |
| 121 | + ..Current,slow pointerPassingstep数为 nb step。therefore,We just find a way slow Go again a step停下来,You can get to the entrance to the ring。 |
| 122 | + |
| 123 | + ...但yes我们不知道 a Value,what to do?依然yes使用双pointer法。我们构建一indivualpointer,此pointer需要have以下性质:此pointerandslow Go forward together a step后,The two nodes at the entrance re -coincide。So where does it need to get to the entrance node? a step?答案yesLinked头部head。 |
| 124 | + |
| 125 | +3. Double pointer met for the second time: |
| 126 | + .slowpointer Unchanged position ,Willfastpointer重新 指向Linked头部节点 ;slowandfast同hour每wheel向前走 1 step; |
| 127 | + |
| 128 | + ..TIPS:此hour f=0,s=nb ; |
| 129 | + ...when fast pointer走到f=a stephour,slow pointer走到steps=a+nb,此hour 两pointer重合,并同hour指向Linked环入口 。 |
| 130 | + |
| 131 | +4. returnslowpointer指向的节点。 |
| 132 | + |
| 133 | +### Complexity analysis: |
| 134 | +hour间复杂度 O(N) :In the second encounter,慢pointer须走step数 a<a+b;First encounter中,慢pointer须走step数 a+b−x<a+b,in x 为双pointer重合点and环入口距离;therefore总体为线性复杂度; |
| 135 | +Spatial complexity O(1) :双pointer使用常数大小的额外空间。 |
| 136 | +<img src="../photos/circle link array 2/Picture1.png" alt="Picture1.png" width="50%" height="50%"> |
| 137 | +<img src="../photos/circle link array 2/Picture2.png" alt="Picture2.png" width="50%" height="50%"> |
| 138 | +<img src="../photos/circle link array 2/Picture3.png" alt="Picture3.png" width="50%" height="50%"> |
| 139 | +<img src="../photos/circle link array 2/Picture4.png" alt="Picture4.png" width="50%" height="50%"> |
| 140 | +<img src="../photos/circle link array 2/Picture5.png" alt="Picture5.png" width="50%" height="50%"> |
| 141 | +<img src="../photos/circle link array 2/Picture6.png" alt="Picture6.png" width="50%" height="50%"> |
| 142 | +<img src="../photos/circle link array 2/Picture7.png" alt="Picture7.png" width="50%" height="50%"> |
| 143 | +<img src="../photos/circle link array 2/Picture8.png" alt="Picture8.png" width="50%" height="50%"> |
| 144 | +<img src="../photos/circle link array 2/Picture9.png" alt="Picture9.png" width="50%" height="50%"> |
| 145 | +<img src="../photos/circle link array 2/Picture10.png" alt="Picture10.png" width="50%" height="50%"> |
| 146 | +<img src="../photos/circle link array 2/Picture11.png" alt="Picture11.png" width="50%" height="50%"> |
| 147 | + |
| 148 | + |
| 149 | + |
| 150 | +# Code: |
| 151 | + |
| 152 | +```python |
| 153 | +class Solution: |
| 154 | + def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: |
| 155 | + a = head |
| 156 | + b = head |
| 157 | + while True: |
| 158 | + if not b or not b.next: |
| 159 | + return None |
| 160 | + a = a.next |
| 161 | + b = b.next.next |
| 162 | + if b == a: |
| 163 | + break |
| 164 | + b = head |
| 165 | + while a != b: |
| 166 | + a, b = a.next, b.next |
| 167 | + return b |
| 168 | +``` |
| 169 | +```C++ |
| 170 | +class Solution { |
| 171 | +public: |
| 172 | + ListNode *detectCycle(ListNode *head) { |
| 173 | + ListNode *a = head; |
| 174 | + ListNode *b = head; |
| 175 | + while (true) { |
| 176 | + if (!b or !b->next) { |
| 177 | + return nullptr; |
| 178 | + } |
| 179 | + a = a->next; |
| 180 | + b = b->next->next; |
| 181 | + //becauseb每次走两step,soabMust meet |
| 182 | + if (a == b) { |
| 183 | + break; |
| 184 | + } |
| 185 | + } |
| 186 | + // After meetingaWait in placeb, b去Linked头部 |
| 187 | + b = head; |
| 188 | + while(a!=b){ |
| 189 | + a = a->next; |
| 190 | + b = b->next; |
| 191 | + } |
| 192 | + |
| 193 | + return a; |
| 194 | + } |
| 195 | +}; |
| 196 | +``` |
0 commit comments