Skip to content

Commit 5ebffe5

Browse files
committed
feat: update solutions to lc/lcci problems: Linked List Cycle I/II
1 parent 233af09 commit 5ebffe5

20 files changed

+840
-157
lines changed

lcci/02.08.Linked List Cycle/README.md

+139-24
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,20 @@
1111

1212
<!-- 这里可写通用的实现逻辑 -->
1313

14+
先利用快慢指针判断链表是否有环,没有环则直接返回 `null`
15+
16+
若链表有环,我们分析快慢相遇时走过的距离。
17+
18+
对于慢指针(每次走 1 步),走过的距离为 `S=X+Y` ①;快指针(每次走 2 步)走过的距离为 `2S=X+Y+N(Y+Z)` ②。如下图所示,其中 `N` 表示快指针与慢指针相遇时在环中所走过的圈数,而我们要求的环入口,也即是 `X` 的距离:
19+
20+
![](./images/linked-list-cycle-ii.png)
21+
22+
我们根据式子 ①②,得出 `X+Y=N(Y+Z)` => `X=(N-1)(Y+Z)+Z`
23+
24+
`N=1`(快指针在环中走了一圈与慢指针相遇) 时,`X=(1-1)(Y+Z)+Z`,即 `X=Z`。此时只要定义一个 `p` 指针指向头节点,然后慢指针与 `p` 开始同时走,当慢指针与 `p` 相遇时,也就到达了环入口,直接返回 `p` 即可。
25+
26+
`N>1`时,也是同样的,说明慢指针除了走 `Z` 步,还需要绕 `N-1` 圈才能与 `p` 相遇。
27+
1428
<!-- tabs:start -->
1529

1630
### **Python3**
@@ -26,17 +40,16 @@
2640

2741
class Solution:
2842
def detectCycle(self, head: ListNode) -> ListNode:
29-
fast = slow = p = head
30-
while fast and fast.next:
31-
fast = fast.next.next
32-
slow = slow.next
33-
if fast == slow:
34-
break
35-
if fast is None or fast.next is None:
43+
slow = fast = head
44+
has_cycle = False
45+
while not has_cycle and fast and fast.next:
46+
slow, fast = slow.next, fast.next.next
47+
has_cycle = slow == fast
48+
if not has_cycle:
3649
return None
37-
while slow != p:
38-
p = p.next
39-
slow = slow.next
50+
p = head
51+
while p != slow:
52+
p, slow = p.next, slow.next
4053
return p
4154
```
4255

@@ -58,20 +71,122 @@ class Solution:
5871
*/
5972
public class Solution {
6073
public ListNode detectCycle(ListNode head) {
61-
ListNode fast = head, slow = head;
62-
while (fast != null && fast.next != null) {
63-
fast = fast.next.next;
64-
slow = slow.next;
65-
if (fast == slow) break;
66-
}
67-
if (fast == null || fast.next == null) return null;
68-
ListNode p = head;
69-
while (p != slow) {
70-
p = p.next;
71-
slow = slow.next;
72-
}
73-
return p;
74+
ListNode slow = head, fast = head;
75+
boolean hasCycle = false;
76+
while (!hasCycle && fast != null && fast.next != null) {
77+
slow = slow.next;
78+
fast = fast.next.next;
79+
hasCycle = slow == fast;
80+
}
81+
if (!hasCycle) {
82+
return null;
83+
}
84+
ListNode p = head;
85+
while (p != slow) {
86+
p = p.next;
87+
slow = slow.next;
88+
}
89+
return p;
90+
}
91+
}
92+
```
93+
94+
### **C++**
95+
96+
```cpp
97+
/**
98+
* Definition for singly-linked list.
99+
* struct ListNode {
100+
* int val;
101+
* ListNode *next;
102+
* ListNode(int x) : val(x), next(NULL) {}
103+
* };
104+
*/
105+
class Solution {
106+
public:
107+
ListNode *detectCycle(ListNode *head) {
108+
ListNode* slow = head;
109+
ListNode* fast = head;
110+
bool hasCycle = false;
111+
while (!hasCycle && fast && fast->next) {
112+
slow = slow->next;
113+
fast = fast->next->next;
114+
hasCycle = slow == fast;
115+
}
116+
if (!hasCycle) {
117+
return nullptr;
118+
}
119+
ListNode* p = head;
120+
while (p != slow) {
121+
p = p->next;
122+
slow = slow->next;
123+
}
124+
return p;
125+
}
126+
};
127+
```
128+
129+
### **JavaScript**
130+
131+
```js
132+
/**
133+
* Definition for singly-linked list.
134+
* function ListNode(val) {
135+
* this.val = val;
136+
* this.next = null;
137+
* }
138+
*/
139+
140+
/**
141+
* @param {ListNode} head
142+
* @return {ListNode}
143+
*/
144+
var detectCycle = function(head) {
145+
let slow = head;
146+
let fast = head;
147+
let hasCycle = false;
148+
while (!hasCycle && fast && fast.next) {
149+
slow = slow.next;
150+
fast = fast.next.next;
151+
hasCycle = slow == fast;
152+
}
153+
if (!hasCycle) {
154+
return null;
155+
}
156+
let p = head;
157+
while (p != slow) {
158+
p = p.next;
159+
slow = slow.next;
160+
}
161+
return p;
162+
};
163+
```
164+
165+
### **Go**
166+
167+
```go
168+
/**
169+
* Definition for singly-linked list.
170+
* type ListNode struct {
171+
* Val int
172+
* Next *ListNode
173+
* }
174+
*/
175+
func detectCycle(head *ListNode) *ListNode {
176+
slow, fast := head, head
177+
hasCycle := false
178+
for !hasCycle && fast != nil && fast.Next != nil {
179+
slow, fast = slow.Next, fast.Next.Next
180+
hasCycle = slow == fast
181+
}
182+
if !hasCycle {
183+
return nil
184+
}
185+
p := head
186+
for p != slow {
187+
p, slow = p.Next, slow.Next
74188
}
189+
return p
75190
}
76191
```
77192

@@ -81,4 +196,4 @@ public class Solution {
81196
82197
```
83198

84-
<!-- tabs:end -->
199+
<!-- tabs:end -->

lcci/02.08.Linked List Cycle/README_EN.md

+96-26
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,13 @@ Can you solve it without using additional space?</p>
5050
# self.next = None
5151

5252
class Solution:
53-
def detectCycle(self, head: ListNode) -> ListNode:
54-
fast = slow = p = head
53+
def hasCycle(self, head: ListNode) -> bool:
54+
slow = fast = head
5555
while fast and fast.next:
56-
fast = fast.next.next
57-
slow = slow.next
58-
if fast == slow:
59-
break
60-
if fast is None or fast.next is None:
61-
return None
62-
while slow != p:
63-
p = p.next
64-
slow = slow.next
65-
return p
56+
slow, fast = slow.next, fast.next.next
57+
if slow == fast:
58+
return True
59+
return False
6660
```
6761

6862
### **Java**
@@ -80,24 +74,100 @@ class Solution:
8074
* }
8175
*/
8276
public class Solution {
83-
public ListNode detectCycle(ListNode head) {
84-
ListNode fast = head, slow = head;
85-
while (fast != null && fast.next != null) {
86-
fast = fast.next.next;
87-
slow = slow.next;
88-
if (fast == slow) break;
89-
}
90-
if (fast == null || fast.next == null) return null;
91-
ListNode p = head;
92-
while (p != slow) {
93-
p = p.next;
94-
slow = slow.next;
95-
}
96-
return p;
77+
public boolean hasCycle(ListNode head) {
78+
ListNode slow = head;
79+
ListNode fast = head;
80+
while (fast != null && fast.next != null) {
81+
slow = slow.next;
82+
fast = fast.next.next;
83+
if (slow == fast) {
84+
return true;
85+
}
86+
}
87+
return false;
9788
}
9889
}
9990
```
10091

92+
### **C++**
93+
94+
```cpp
95+
/**
96+
* Definition for singly-linked list.
97+
* struct ListNode {
98+
* int val;
99+
* ListNode *next;
100+
* ListNode(int x) : val(x), next(NULL) {}
101+
* };
102+
*/
103+
class Solution {
104+
public:
105+
bool hasCycle(ListNode *head) {
106+
ListNode* slow = head;
107+
ListNode* fast = head;
108+
while (fast && fast->next) {
109+
slow = slow->next;
110+
fast = fast->next->next;
111+
if (slow == fast) {
112+
return true;
113+
}
114+
}
115+
return false;
116+
}
117+
};
118+
```
119+
120+
### **JavaScript**
121+
122+
```js
123+
/**
124+
* Definition for singly-linked list.
125+
* function ListNode(val) {
126+
* this.val = val;
127+
* this.next = null;
128+
* }
129+
*/
130+
131+
/**
132+
* @param {ListNode} head
133+
* @return {boolean}
134+
*/
135+
var hasCycle = function(head) {
136+
let slow = head;
137+
let fast = head;
138+
while (fast && fast.next) {
139+
slow = slow.next;
140+
fast = fast.next.next;
141+
if (slow == fast) {
142+
return true;
143+
}
144+
}
145+
return false;
146+
};
147+
```
148+
149+
### **Go**
150+
151+
```go
152+
/**
153+
* Definition for singly-linked list.
154+
* type ListNode struct {
155+
* Val int
156+
* Next *ListNode
157+
* }
158+
*/
159+
func hasCycle(head *ListNode) bool {
160+
slow, fast := head, head
161+
for fast != nil && fast.Next != nil {
162+
slow, fast = slow.Next, fast.Next.Next
163+
if slow == fast {
164+
return true
165+
}
166+
}
167+
return false
168+
}
169+
```
170+
101171
### **...**
102172

103173
```
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Definition for singly-linked list.
3+
* struct ListNode {
4+
* int val;
5+
* ListNode *next;
6+
* ListNode(int x) : val(x), next(NULL) {}
7+
* };
8+
*/
9+
class Solution {
10+
public:
11+
ListNode *detectCycle(ListNode *head) {
12+
ListNode* slow = head;
13+
ListNode* fast = head;
14+
bool hasCycle = false;
15+
while (!hasCycle && fast && fast->next) {
16+
slow = slow->next;
17+
fast = fast->next->next;
18+
hasCycle = slow == fast;
19+
}
20+
if (!hasCycle) {
21+
return nullptr;
22+
}
23+
ListNode* p = head;
24+
while (p != slow) {
25+
p = p->next;
26+
slow = slow->next;
27+
}
28+
return p;
29+
}
30+
};
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Definition for singly-linked list.
3+
* type ListNode struct {
4+
* Val int
5+
* Next *ListNode
6+
* }
7+
*/
8+
func detectCycle(head *ListNode) *ListNode {
9+
slow, fast := head, head
10+
hasCycle := false
11+
for !hasCycle && fast != nil && fast.Next != nil {
12+
slow, fast = slow.Next, fast.Next.Next
13+
hasCycle = slow == fast
14+
}
15+
if !hasCycle {
16+
return nil
17+
}
18+
p := head
19+
for p != slow {
20+
p, slow = p.Next, slow.Next
21+
}
22+
return p
23+
}

0 commit comments

Comments
 (0)