Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5a8ae3f

Browse files
feat: add solutions to lcci/lcof2 problems (doocs#2530)
* lcci No.02.08.Linked List Cycle * lcof2 No.022.链表中环的入口节点 * lcof2 No.023.两个链表的第一个重合节点
1 parent 1f10d17 commit 5a8ae3f

File tree

24 files changed

+618
-428
lines changed

24 files changed

+618
-428
lines changed

‎.github/pull_request_template.md‎

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1 @@
11

2-
3-
<!--
4-
Below are template for copilot to generate CR message.
5-
Please DO NOT modify it.
6-
7-
8-
### Description
9-
10-
copilot:summary
11-
12-
### Explanation of Changes
13-
14-
copilot:walkthrough
15-
16-
-->

‎lcci/02.08.Linked List Cycle/README.md‎

Lines changed: 107 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,25 @@
1010

1111
## 解法
1212

13-
### 方法一
13+
### 方法一:快慢指针
14+
15+
我们先利用快慢指针判断链表是否有环,如果有环的话,快慢指针一定会相遇,且相遇的节点一定在环中。
16+
17+
如果没有环,快指针会先到达链表尾部,直接返回 `null` 即可。
18+
19+
如果有环,我们再定义一个答案指针 $ans$ 指向链表头部,然后让 $ans$ 和慢指针一起向前走,每次走一步,直到 $ans$ 和慢指针相遇,相遇的节点即为环的入口节点。
20+
21+
为什么这样能找到环的入口节点呢?
22+
23+
我们不妨假设链表头节点到环入口的距离为 $x,ドル环入口到相遇节点的距离为 $y,ドル相遇节点到环入口的距离为 $z,ドル那么慢指针走过的距离为 $x + y,ドル快指针走过的距离为 $x + y + k \times (y + z),ドル其中 $k$ 是快指针在环中绕了 $k$ 圈。
24+
25+
<p><img src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/lcci/02.08.Linked%20List%20Cycle/images/linked-list-cycle-ii.png" /></p>
26+
27+
由于快指针速度是慢指针的 2ドル$ 倍,因此有 2ドル \times (x + y) = x + y + k \times (y + z),ドル可以推出 $x + y = k \times (y + z),ドル即 $x = (k - 1) \times (y + z) + z$。
28+
29+
也即是说,如果我们定义一个答案指针 $ans$ 指向链表头部,然后 $ans$ 和慢指针一起向前走,那么它们一定会在环入口相遇。
30+
31+
时间复杂度 $O(n),ドル其中 $n$ 是链表中节点的数目。空间复杂度 $O(1)$。
1432

1533
<!-- tabs:start -->
1634

@@ -23,18 +41,17 @@
2341

2442

2543
class Solution:
26-
def detectCycle(self, head: ListNode) -> ListNode:
27-
slow = fast = head
28-
has_cycle = False
29-
while not has_cycle and fast and fast.next:
30-
slow, fast = slow.next, fast.next.next
31-
has_cycle = slow == fast
32-
if not has_cycle:
33-
return None
34-
p = head
35-
while p != slow:
36-
p, slow = p.next, slow.next
37-
return p
44+
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
45+
fast = slow = head
46+
while fast and fast.next:
47+
slow = slow.next
48+
fast = fast.next.next
49+
if slow == fast:
50+
ans = head
51+
while ans != slow:
52+
ans = ans.next
53+
slow = slow.next
54+
return ans
3855
```
3956

4057
```java
@@ -51,22 +68,20 @@ class Solution:
5168
*/
5269
public class Solution {
5370
public ListNode detectCycle(ListNode head) {
54-
ListNode slow = head, fast = head;
55-
boolean hasCycle = false;
56-
while (!hasCycle && fast != null && fast.next != null) {
71+
ListNode fast = head, slow = head;
72+
while (fast != null && fast.next != null) {
5773
slow = slow.next;
5874
fast = fast.next.next;
59-
hasCycle = slow == fast;
75+
if (slow == fast) {
76+
ListNode ans = head;
77+
while (ans != slow) {
78+
ans = ans.next;
79+
slow = slow.next;
80+
}
81+
return ans;
82+
}
6083
}
61-
if (!hasCycle) {
62-
return null;
63-
}
64-
ListNode p = head;
65-
while (p != slow) {
66-
p = p.next;
67-
slow = slow.next;
68-
}
69-
return p;
84+
return null;
7085
}
7186
}
7287
```
@@ -83,23 +98,21 @@ public class Solution {
8398
class Solution {
8499
public:
85100
ListNode* detectCycle(ListNode* head) {
86-
ListNode* slow = head;
87101
ListNode* fast = head;
88-
bool hasCycle = false;
89-
while (!hasCycle && fast && fast->next) {
102+
ListNode* slow = head;
103+
while (fast && fast->next) {
90104
slow = slow->next;
91105
fast = fast->next->next;
92-
hasCycle = slow == fast;
93-
}
94-
if (!hasCycle) {
95-
return nullptr;
106+
if (slow == fast) {
107+
ListNode* ans = head;
108+
while (ans != slow) {
109+
ans = ans->next;
110+
slow = slow->next;
111+
}
112+
return ans;
113+
}
96114
}
97-
ListNode* p = head;
98-
while (p != slow) {
99-
p = p->next;
100-
slow = slow->next;
101-
}
102-
return p;
115+
return nullptr;
103116
}
104117
};
105118
```
@@ -113,20 +126,51 @@ public:
113126
* }
114127
*/
115128
func detectCycle(head *ListNode) *ListNode {
116-
slow, fast := head, head
117-
hasCycle := false
118-
for !hasCycle && fast != nil && fast.Next != nil {
119-
slow, fast = slow.Next, fast.Next.Next
120-
hasCycle = slow == fast
121-
}
122-
if !hasCycle {
123-
return nil
129+
fast, slow := head, head
130+
for fast != nil && fast.Next != nil {
131+
slow = slow.Next
132+
fast = fast.Next.Next
133+
if slow == fast {
134+
ans := head
135+
for ans != slow {
136+
ans = ans.Next
137+
slow = slow.Next
138+
}
139+
return ans
140+
}
124141
}
125-
p := head
126-
for p != slow {
127-
p, slow = p.Next, slow.Next
128-
}
129-
return p
142+
return nil
143+
}
144+
```
145+
146+
```ts
147+
/**
148+
* Definition for singly-linked list.
149+
* class ListNode {
150+
* val: number
151+
* next: ListNode | null
152+
* constructor(val?: number, next?: ListNode | null) {
153+
* this.val = (val===undefined ? 0 : val)
154+
* this.next = (next===undefined ? null : next)
155+
* }
156+
* }
157+
*/
158+
159+
function detectCycle(head: ListNode | null): ListNode | null {
160+
let [slow, fast] = [head, head];
161+
while (fast && fast.next) {
162+
slow = slow.next;
163+
fast = fast.next.next;
164+
if (slow === fast) {
165+
let ans = head;
166+
while (ans !== slow) {
167+
ans = ans.next;
168+
slow = slow.next;
169+
}
170+
return ans;
171+
}
172+
}
173+
return null;
130174
}
131175
```
132176

@@ -144,26 +188,19 @@ func detectCycle(head *ListNode) *ListNode {
144188
* @return {ListNode}
145189
*/
146190
var detectCycle = function (head) {
147-
let slow = head;
148-
let fast = head;
149-
let hasCycle = false;
150-
while (!hasCycle && fast && fast.next) {
191+
let [slow, fast] = [head, head];
192+
while (fast && fast.next) {
151193
slow = slow.next;
152194
fast = fast.next.next;
153-
hasCycle = slow == fast;
154-
}
155-
if (!hasCycle) {
156-
return null;
157-
}
158-
let p = head;
159-
while (p != slow) {
160-
p = p.next;
161-
slow = slow.next;
195+
if (slow === fast) {
196+
let ans = head;
197+
while (ans !== slow) {
198+
ans = ans.next;
199+
slow = slow.next;
200+
}
201+
return ans;
202+
}
162203
}
163-
return p;
204+
return null;
164205
};
165206
```
166-
167-
<!-- tabs:end -->
168-
169-
<!-- end -->

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /