@@ -46,6 +46,8 @@ public class Solution {
46
46
}
47
47
```
48
48
49
+ 其它语言的代码请参考[ 这里] ( https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E9%93%BE%E8%A1%A8%E7%AF%87/leetcode141%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8.md ) 。
50
+
49
51
判断链表是不是含有环很简单,但是我们想找到环的入口可能就没有那么容易了。(入口则为下图绿色节点)
50
52
51
53
然后我们返回的则为绿色节点的索引,则返回2。
@@ -62,23 +64,22 @@ public class Solution {
62
64
63
65
![ image-20201027182649669] ( https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/image-20201027182649669.2g8gq4ik6xs0.png )
64
66
65
-
67
+ Java Code:
66
68
67
69
``` java
68
70
public class Solution {
69
71
public ListNode detectCycle (ListNode head ) {
70
-
71
72
if (head == null ) {
72
73
return head;
73
74
}
74
75
if (head. next == null ) {
75
76
return head. next;
76
77
}
77
- // 创建新的HashSet, 用于保存节点
78
+ // 创建新的HashSet, 用于保存节点
78
79
HashSet<ListNode > hash = new HashSet<ListNode > ();
79
80
// 遍历链表
80
81
while (head != null ) {
81
- // 判断哈希表中是否含有某节点,没有则保存,含有则返回该节点
82
+ // 判断哈希表中是否含有某节点,没有则保存,含有则返回该节点
82
83
if (hash. contains(head)) {
83
84
return head;
84
85
}
@@ -91,6 +92,70 @@ public class Solution {
91
92
}
92
93
```
93
94
95
+ C++ Code:
96
+
97
+ ``` cpp
98
+ class Solution {
99
+ public:
100
+ ListNode * detectCycle(ListNode * head) {
101
+ if (head == nullptr) return head;
102
+ if (head->next == nullptr) return head->next;
103
+ set<ListNode * > hash;
104
+ while (head != nullptr) {
105
+ if (hash.count(head)) {
106
+ return head;
107
+ }
108
+ hash.insert(head);
109
+ head = head->next;
110
+ }
111
+ return head;
112
+ }
113
+ };
114
+ ```
115
+
116
+ JS Code:
117
+
118
+ ```javascript
119
+ var detectCycle = function(head) {
120
+ if (head === null) return head;
121
+ if (head.next === null) return head.next;
122
+ //创建新的HashSet,用于保存节点
123
+ let hash = new Set();
124
+ //遍历链表
125
+ while (head !== null) {
126
+ //判断哈希表中是否含有某节点,没有则保存,含有则返回该节点
127
+ if (hash.has(head)) {
128
+ return head;
129
+ }
130
+ //不含有,则进行保存,并移动指针
131
+ hash.add(head);
132
+ head = head.next;
133
+ }
134
+ return head;
135
+ };
136
+ ```
137
+
138
+ Python Code:
139
+
140
+ ``` py
141
+ class Solution :
142
+ def detectCycle (self , head : ListNode) -> ListNode:
143
+ if head is None :
144
+ return head
145
+ if head.next is None :
146
+ return head.next
147
+ # 创建新的HashSet,用于保存节点
148
+ hash = set ()
149
+ while head is not None :
150
+ # 判断哈希表中是否含有某节点,没有则保存,含有则返回该节点
151
+ if head in hash :
152
+ return head
153
+ # 不含有,则进行保存,并移动指针
154
+ hash .add(head)
155
+ head = head.next
156
+ return head
157
+ ```
158
+
94
159
95
160
96
161
### 快慢指针
@@ -101,25 +166,25 @@ public class Solution {
101
166
102
167
上图黄色节点为快慢指针相遇的节点,此时
103
168
104
- 快指针走的距离:** a+(b+c)n+b**
169
+ 快指针走的距离:** a+(b+c)n+b** ,n代表圈数。
105
170
106
171
很容易理解b+c为环的长度,a为直线距离,b为绕了n圈之后又走了一段距离才相遇,所以相遇时走的总路程为a+(b+c)n+b,合并同类项得a+(n+1)b+nc。
107
172
108
- 慢指针走的距离:** a+(b+c)m+b** , m代表圈数。
173
+ 慢指针走的距离:** a+(b+c)m+b** , m代表圈数。
109
174
110
- 然后我们设快指针得速度是慢指针的2倍, 含义为相同时间内,快指针走过的距离是慢指针的2倍。
175
+ 然后我们设快指针得速度是慢指针的2倍, 含义为相同时间内,快指针走过的距离是慢指针的2倍。
111
176
112
- ** a+(n+1)b+nc=2[ a+(m+1)b+mc] ** 整理得** a+b=(n-2m)(b+c),** 那么我们可以从这个等式上面发现什么呢?** b+c **
177
+ ** a+(n+1)b+nc=2[ a+(m+1)b+mc] ** 整理得** a+b=(n-2m)(b+c),** 那么我们可以从这个等式上面发现什么呢?
113
178
114
- 为一圈的长度。也就是说a+b等于n-2m个环的长度。为了便于理解我们看一种特殊情况,当n-2m等于1,那么a+b=b+c整理得,a=c此时我们只需重新释放两个指针 ,一个从head释放,一个从相遇点释放,速度相同,因为a=c所以他俩必会在环入口处相遇,则求得入口节点索引。
179
+ ** b+c ** 为一圈的长度。也就是说a+b等于n-2m个环的长度。为了便于理解我们看一种特殊情况,当n-2m等于1,那么a+b=b+c整理得,a=c。此时我们只需重新释放两个指针 ,一个从head释放,一个从相遇点释放,速度相同,因为a=c所以他俩必会在环入口处相遇,则求得入口节点索引。
115
180
116
181
算法流程:
117
182
118
- 1.设置快慢指针,快指针速度为慢指针的2倍
183
+ 1.设置快慢指针,快指针速度为慢指针的2倍。
119
184
120
- 2.找出相遇点
185
+ 2.找出相遇点。
121
186
122
- 3.在head处和相遇点同时释放相同速度且速度为1的指针,两指针必会在环入口处相遇
187
+ 3.在head处和相遇点同时释放相同速度且速度为1的指针,两指针必会在环入口处相遇。
123
188
124
189
![ 环形链表2] ( https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/环形链表2.elwu1pw2lw0.gif )
125
190
@@ -150,7 +215,6 @@ public class Solution {
150
215
}
151
216
}
152
217
return null ;
153
-
154
218
}
155
219
}
156
220
```
0 commit comments