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 c6d4ef2

Browse files
update md files
update README.md
1 parent dbf1e8e commit c6d4ef2

File tree

14 files changed

+1270
-0
lines changed

14 files changed

+1270
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
2+
3+
# 141 : 环形链表
4+
5+
## 📌题目详情
6+
7+
[leetcode 题目地址](https://leetcode.com/problems/linked-list-cycle/)
8+
9+
[leetcode-cn 题目地址](https://leetcode-cn.com/problems/linked-list-cycle/)
10+
11+
📗Difficulty:**Easy**
12+
13+
🎯Tags:
14+
15+
+ **[链表](https://leetcode-cn.com/tag/linked-list/)**
16+
+ **[双指针](https://leetcode-cn.com/tag/two-pointers/)**
17+
18+
---
19+
20+
## 📃题目描述
21+
22+
给定一个链表,判断链表中是否有环。
23+
24+
为了表示给定链表中的环,我们使用整数 `pos` 来表示链表尾连接到链表中的位置(索引从 `0` 开始)。 如果 `pos``-1`,则在该链表中没有环。
25+
26+
27+
28+
**样例 1:**
29+
30+
```
31+
输入:head = [3,2,0,-4], pos = 1
32+
输出:true
33+
解释:链表中有一个环,其尾部连接到第二个节点。
34+
```
35+
36+
![](https://assets.ryantech.ltd/20200811140348.png)
37+
38+
39+
40+
**样例 2:**
41+
42+
```
43+
输入:head = [1,2], pos = 0
44+
输出:true
45+
解释:链表中有一个环,其尾部连接到第一个节点。
46+
```
47+
48+
![](https://assets.ryantech.ltd/20200811140413.png)
49+
50+
**进阶**
51+
52+
+ 你能用 `O(1)`(即,常量)内存解决此问题吗?
53+
54+
55+
56+
****
57+
58+
## 🏹🎯解题思路
59+
60+
对于链表的遍历操作,一般的代码框架为:
61+
62+
```java
63+
void traverse(ListNode head) {
64+
for (ListNode q = head; q != null; q = q.next) {
65+
// ...
66+
}
67+
}
68+
```
69+
70+
但是,本题的描述下,如果出现了环,那么会陷入无限循环,没法停下来。需要找到一个使得循环停下来的条件,才能完成题目。
71+
72+
73+
74+
> 以下思路来自 [《经典面试题:环形链表的判断与定位》](https://mp.weixin.qq.com/s/RTmeolRW4Z2o7HcdWx4tdg) 的思路,感谢作者的细心和详细的分析。
75+
76+
### 使用 哈希表 记录元素
77+
78+
在 Java 中借用 `HashSet` 可以快速查询一个元素是否出现过,并且时间复杂度为 `O(1)`。可以将整体的时间复杂度控制在 `O(n)`
79+
80+
81+
82+
#### 代码实现
83+
84+
```java
85+
public boolean hasCycle(ListNode head) {
86+
// 记录已访问过的结点
87+
Set<ListNode> seen = new HashSet<>();
88+
for (ListNode q = head; q != null; q = q.next) {
89+
if (seen.contains(q)) {
90+
// 遇到已访问过的结点,确定链表存在环
91+
return true;
92+
}
93+
seen.add(q);
94+
}
95+
// 遍历循环正常退出,链表不存在环
96+
return false;
97+
}
98+
99+
public static void main(String[] args) {
100+
ListNode head = new ListNode(3);
101+
head.next = new ListNode(2);
102+
ListNode cycle = head.next;
103+
head.next.next = new ListNode(0);
104+
head.next.next.next = new ListNode(-4);
105+
head.next.next.next.next = cycle;
106+
System.out.println(new Solution2().hasCycle(head));
107+
}
108+
```
109+
110+
111+
112+
#### 复杂度分析
113+
114+
+ 时间复杂度:`O(n)`
115+
+ 空间复杂度:`O(n)`
116+
117+
---
118+
119+
### 快慢双指针 巧解
120+
121+
如果需要更加进一步优化空间复杂度,就需要用到快慢指针了。
122+
123+
这样的思路,需要多做题目,多做总结,一般来说,在初次遇见时,不加提醒,很难想到这样的思路。
124+
125+
126+
127+
#### 代码实现
128+
129+
```java
130+
// 快慢双指针 解法
131+
public boolean hasCycle(ListNode head) {
132+
ListNode slow = head;
133+
ListNode fast = head;
134+
// 注意 while 循环的条件
135+
while (fast != null && fast.next != null) {
136+
slow = slow.next;
137+
fast = fast.next.next;
138+
if (slow == fast) {
139+
return true;
140+
}
141+
}
142+
return false;
143+
}
144+
```
145+
146+
147+
148+
#### 复杂度分析
149+
150+
+ 时间复杂度:`O(n)`
151+
+ 空间复杂度:`O(1)`
152+
153+
154+
155+
---
156+
157+
## 💡总结
158+
159+
#### 进阶
160+
161+
[142. 环形链表 II](https://leetcode-cn.com/problems/linked-list-cycle-ii/) ,在本题基础上,需要求解出循环的起点。思考如果在快慢指针的基础上,进行一定的代码修改?
162+
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
2+
3+
# 142 : 环形链表 II
4+
5+
## 📌题目详情
6+
7+
[leetcode 题目地址](https://leetcode.com/problems/linked-list-cycle-ii/)
8+
9+
[leetcode-cn 题目地址](https://leetcode-cn.com/problems/linked-list-cycle-ii/)
10+
11+
📗Difficulty:**Medium**
12+
13+
🎯Tags:
14+
15+
+ **[链表](https://leetcode-cn.com/tag/linked-list/)**
16+
+ **[双指针](https://leetcode-cn.com/tag/two-pointers/)**
17+
18+
---
19+
20+
## 📃题目描述
21+
22+
给定一个链表,判断链表中是否有环。
23+
24+
为了表示给定链表中的环,我们使用整数 `pos` 来表示链表尾连接到链表中的位置(索引从 `0` 开始)。 如果 `pos``-1`,则在该链表中没有环。
25+
26+
27+
28+
**样例 1:**
29+
30+
```
31+
输入:head = [3,2,0,-4], pos = 1
32+
输出:true
33+
解释:链表中有一个环,其尾部连接到第二个节点。
34+
```
35+
36+
![](https://assets.ryantech.ltd/20200811140348.png)
37+
38+
39+
40+
**样例 2:**
41+
42+
```
43+
输入:head = [1,2], pos = 0
44+
输出:true
45+
解释:链表中有一个环,其尾部连接到第一个节点。
46+
```
47+
48+
![](https://assets.ryantech.ltd/20200811140413.png)
49+
50+
**进阶**
51+
52+
+ 你能用 `O(1)`(即,常量)内存解决此问题吗?
53+
54+
55+
56+
****
57+
58+
## 🏹🎯解题思路
59+
60+
对于链表的遍历操作,一般的代码框架为:
61+
62+
```java
63+
void traverse(ListNode head) {
64+
for (ListNode q = head; q != null; q = q.next) {
65+
// ...
66+
}
67+
}
68+
```
69+
70+
但是,本题的描述下,如果出现了环,那么会陷入无限循环,没法停下来。需要找到一个使得循环停下来的条件,才能完成题目。
71+
72+
73+
74+
> 以下思路来自 [《经典面试题:环形链表的判断与定位》](https://mp.weixin.qq.com/s/RTmeolRW4Z2o7HcdWx4tdg) 的思路,感谢作者的细心和详细的分析。
75+
76+
### 快慢双指针 巧解
77+
78+
如果需要更加进一步优化空间复杂度,就需要用到快慢指针了。
79+
80+
这样的思路,需要多做题目,多做总结,一般来说,在初次遇见时,不加提醒,很难想到这样的思路。
81+
82+
83+
84+
乍一看来,这道题挺难的。我们可以用快慢指针的方法知道链表中是否存在环,但我们不知道两个指针相遇在什么位置,要找到环的起点就更难了。不过不要慌,我们先画个图看看两个指针相遇的过程:
85+
86+
![](https://assets.ryantech.ltd/20200811144650.jpg)
87+
88+
![](https://assets.ryantech.ltd/20200811144934.png)
89+
90+
91+
92+
#### 代码实现
93+
94+
```java
95+
// 快慢双指针 解法
96+
public boolean hasCycle(ListNode head) {
97+
ListNode slow = head;
98+
ListNode fast = head;
99+
// 注意 while 循环的条件
100+
while (fast != null && fast.next != null) {
101+
slow = slow.next;
102+
fast = fast.next.next;
103+
if (slow == fast) {
104+
return true;
105+
}
106+
}
107+
return false;
108+
}
109+
```
110+
111+
112+
113+
#### 复杂度分析
114+
115+
+ 时间复杂度:`O(n)`
116+
+ 空间复杂度:`O(1)`
117+
118+
119+
120+
---
121+
122+
## 💡总结
123+
124+
![](https://assets.ryantech.ltd/20200811145020.png)
125+
126+
127+

0 commit comments

Comments
(0)

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