Skip to content

Commit 9a42764

Browse files
committed
update 20 24 25 92 133 224
1 parent 9ac7bbd commit 9a42764

File tree

8 files changed

+263
-179
lines changed

8 files changed

+263
-179
lines changed

assets/output/0092.md

Lines changed: 0 additions & 52 deletions
This file was deleted.

assets/output/0138.md

Lines changed: 0 additions & 80 deletions
This file was deleted.

src/leetcode/problem/0020.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,24 @@ var isValid = function (s) {
8080
}
8181
return stack.length === 0;
8282
};
83+
84+
// 简化写法
85+
var isValid = function (s) {
86+
let stack = [],
87+
obj = {
88+
')': '(',
89+
']': '[',
90+
'}': '{'
91+
};
92+
for (let item of s) {
93+
if ('[{('.indexOf(item) != -1) {
94+
stack.push(item);
95+
} else if (obj[item] != stack.pop()) {
96+
return false;
97+
}
98+
}
99+
return stack.length == 0;
100+
};
83101
```
84102

85103
## 相关题目

src/leetcode/problem/0024.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,43 @@ only nodes themselves may be changed.)
3434

3535
## 题目大意
3636

37-
两两相邻的元素,翻转链表
37+
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
3838

3939
## 解题思路
4040

41-
按照题意做即可。
41+
### 思路一:迭代法
42+
43+
1. 使用一个虚拟头节点 `res` 作为新链表的头,避免处理头节点时的边界问题;
44+
2. 初始化 `prev` 指针指向虚拟头节点;
45+
3. 使用 `prev` 指针来遍历链表,每次交换相邻的节点 `prev.next``prev.next.next`,并更新 `prev` 指针,使其指向交换后的第二个节点;
46+
4. 遍历的终止条件是:`prev.next``prev.next.next` 不存在了,即剩余节点不足两个;
47+
5. 返回结果;
48+
49+
### 思路二:递归法
50+
51+
1. 递归终止条件:如果链表为空或只有一个节点,则返回原链表,因为没有节点可交换;
52+
2. 交换节点:交换当前节点对,并将交换后的链表头设置为 second,递归处理剩下的链表 rest;
53+
3. 返回新头节点:返回新的链表头 second;
4254

4355
## 代码
4456

57+
:::: code-tabs
58+
59+
@tab 迭代法
60+
4561
```javascript
4662
/**
4763
* @param {ListNode} head
4864
* @return {ListNode}
4965
*/
5066
var swapPairs = function (head) {
67+
// 构造虚拟头节点
5168
let res = new ListNode(0, head);
5269
let prev = res;
5370

71+
// 遍历链表
5472
while (prev.next && prev.next.next) {
73+
// 交换前两个节点
5574
let cur = prev.next;
5675
let temp = cur.next;
5776
cur.next = temp.next;
@@ -63,6 +82,35 @@ var swapPairs = function (head) {
6382
};
6483
```
6584

85+
@tab 递归法
86+
87+
```javascript
88+
/**
89+
* @param {ListNode} head
90+
* @return {ListNode}
91+
*/
92+
var swapPairs = function (head) {
93+
// 如果链表为空或只有一个节点,不需要交换
94+
if (!head || !head.next) {
95+
return head;
96+
}
97+
98+
// 交换前两个节点
99+
let first = head;
100+
let second = head.next;
101+
let rest = second.next;
102+
103+
// 递归处理剩下的链表
104+
second.next = first;
105+
first.next = swapPairs(rest);
106+
107+
// 返回新头节点
108+
return second;
109+
};
110+
```
111+
112+
::::
113+
66114
## 相关题目
67115

68116
:::: md-demo 相关题目

src/leetcode/problem/0025.md

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,111 @@ changed.
4040

4141
## 题目大意
4242

43-
按照每 K 个元素翻转的方式翻转链表。如果不满足 K 个元素的就不翻转。
43+
给你链表的头节点 `head` ,每 `k` 个节点一组进行翻转,请你返回修改后的链表。
44+
45+
`k` 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 `k` 的整数倍,那么请将最后剩余的节点保持原有顺序。
46+
47+
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
4448

4549
## 解题思路
4650

47-
这一题是 [第 24 题](./0024.md) 的加强版,第 24 题是两两相邻的元素,翻转链表。而本题要求的是 k 个相邻的元素,翻转链表,第 24 题相当于是 k = 2 的特殊情况。
51+
这一题是 [第 24 题](./0024.md) 的加强版,第 24 题是两两相邻的元素,翻转链表。而本题要求的是 `k` 个相邻的元素,翻转链表,第 24 题相当于是 `k = 2` 的特殊情况。
52+
53+
### 思路一:迭代法
54+
55+
1. 使用 `dummy` 作为虚拟头节点,方便处理链表的连接和首节点的反转;
56+
2. 首先遍历链表,获取链表长度 `length`,用于判断是否有足够的 `k` 个节点进行反转;
57+
3. 每次找到 `k` 个节点进行反转,通过循环来交换节点的位置,并保持链表正确的连接顺序;
58+
4. 反转完成后,将指针 `prev` 移动到下一组的前一个节点,继续遍历下一组 `k` 个节点,直到剩余节点不足 `k`
59+
60+
- 时间复杂度为 `O(n)`
61+
- 空间复杂度为 `O(1)`
62+
63+
### 思路二:递归法
64+
65+
1. **判断是否足够 `k` 个节点**:在每次递归之前,遍历前 `k` 个节点,判断是否有足够的 `k` 个节点。如果不足 `k` 个,则直接返回当前链表,不进行反转。
66+
2. **反转前 `k` 个节点**:通过循环逐个反转 `k` 个节点。使用 `prev` 来记录已经反转的部分,`curr` 用来遍历当前节点,`next` 记录下一个节点的位置。
67+
3. **递归处理剩余部分**:在反转 `k` 个节点后,递归处理剩余的链表部分,并将递归结果连接到反转后的链表。
68+
4. **返回结果**:每次递归都返回反转后的链表头节点。
69+
70+
- 时间复杂度为 `O(n)`
71+
- 递归方式更加直观,反转过程简洁,但递归栈的深度为 `O(n/k)`,因此空间复杂度为 `O(n/k)`
4872

4973
## 代码
5074

75+
:::: code-tabs
76+
@tab 迭代法
77+
78+
```javascript
79+
var reverseKGroup = function (head, k) {
80+
// 创建虚拟头节点,方便处理链表连接
81+
let dummy = new ListNode(0);
82+
dummy.next = head;
83+
let prev = dummy;
84+
85+
// 统计链表长度
86+
let length = 0;
87+
let temp = head;
88+
while (temp) {
89+
length++;
90+
temp = temp.next;
91+
}
92+
93+
// 逐步反转每组k个节点
94+
while (length >= k) {
95+
let curr = prev.next;
96+
let next = curr.next;
97+
for (let i = 1; i < k; i++) {
98+
curr.next = next.next;
99+
next.next = prev.next;
100+
prev.next = next;
101+
next = curr.next;
102+
}
103+
// 移动指针到下一组
104+
prev = curr;
105+
length -= k;
106+
}
107+
108+
return dummy.next;
109+
};
110+
```
111+
112+
@tab 递归法
113+
114+
```javascript
115+
var reverseKGroup = function (head, k) {
116+
// 判断剩余节点是否足够k个,不够则返回原链表
117+
let count = 0;
118+
let node = head;
119+
while (count < k && node) {
120+
node = node.next;
121+
count++;
122+
}
123+
if (count < k) {
124+
return head;
125+
}
126+
127+
// 反转前k个节点
128+
let prev = null;
129+
let curr = head;
130+
let next = null;
131+
for (let i = 0; i < k; i++) {
132+
next = curr.next;
133+
curr.next = prev;
134+
prev = curr;
135+
curr = next;
136+
}
137+
138+
// 递归处理剩下的链表,并连接到反转后的链表
139+
head.next = reverseKGroup(curr, k);
140+
141+
// 返回反转后的头节点
142+
return prev;
143+
};
144+
```
145+
146+
@tab 递归法二
147+
51148
```javascript
52149
/**
53150
* @param {ListNode} head
@@ -89,6 +186,8 @@ var reverse = function (first, last) {
89186
};
90187
```
91188

189+
::::
190+
92191
## 相关题目
93192

94193
:::: md-demo 相关题目

0 commit comments

Comments
 (0)