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 59d86b7

Browse files
committed
更新题解列表
1 parent b8d8e66 commit 59d86b7

File tree

5 files changed

+284
-12
lines changed

5 files changed

+284
-12
lines changed

‎Solutions/0002. 两数相加.md‎

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,42 @@
55

66
## 题目大意
77

8-
描述:给定两个非空的链表 `l1``l2`。分别用来表示两个非负整数,每位数字都是按照逆序的方式存储的,每个节点存储一位数字。
8+
**描述**:给定两个非空的链表 `l1``l2`。分别用来表示两个非负整数,每位数字都是按照逆序的方式存储的,每个节点存储一位数字。
99

10-
要求:计算两个非负整数的和,并逆序返回表示和的链表。
10+
**要求**:计算两个非负整数的和,并逆序返回表示和的链表。
11+
12+
**说明**:
13+
14+
- 每个链表中的节点数在范围 $[1, 100]$ 内。
15+
- 0ドル \le Node.val \le 9$。
16+
- 题目数据保证列表表示的数字不含前导零。
17+
18+
**示例**:
19+
20+
- 示例 1:
21+
22+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2021/01/02/addtwonumber1.jpg)
23+
24+
```Python
25+
输入:l1 = [2,4,3], l2 = [5,6,4]
26+
输出:[7,0,8]
27+
解释:342 + 465 = 807.
28+
```
29+
30+
- 示例 2:
31+
32+
```Python
33+
输入:l1 = [0], l2 = [0]
34+
输出:[0]
35+
```
1136

1237
## 解题思路
1338

14-
模拟大数加法,按位相加,将结果添加到新链表上。需要注意进位和对 10 取余。
39+
### 思路 1:模拟
40+
41+
模拟大数加法,按位相加,将结果添加到新链表上。需要注意进位和对 10ドル$ 取余。
1542

16-
##代码
43+
### 思路 1:代码
1744

1845
```Python
1946
class Solution:
@@ -41,3 +68,7 @@ class Solution:
4168
return head.next
4269
```
4370

71+
### 思路 1:复杂度分析
72+
73+
- **时间复杂度**:$O(max(m, n))$。其中,$m$ 和 $n$ 分别是链表 `l1``l2` 的长度。
74+
- **空间复杂度**:$O(1)$。
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# [0032. 最长有效括号](https://leetcode.cn/problems/longest-valid-parentheses/)
2+
3+
- 标签:栈、字符串、动态规划
4+
- 难度:困难
5+
6+
## 题目大意
7+
8+
**描述**:给定一个只包含 `'('``')'` 的字符串。
9+
10+
**要求**:找出最长有效(格式正确且连续)括号子串的长度。
11+
12+
**说明**:
13+
14+
- 0ドル \le s.length \le 3 * 10^4$。
15+
- `s[i]``'('``')'`
16+
17+
**示例**:
18+
19+
- 示例 1:
20+
21+
```Python
22+
输入:s = "(()"
23+
输出:2
24+
解释:最长有效括号子串是 "()"
25+
```
26+
27+
- 示例 2:
28+
29+
```Python
30+
输入:s = ")()())"
31+
输出:4
32+
解释:最长有效括号子串是 "()()"
33+
```
34+
35+
## 解题思路
36+
37+
### 思路 1:动态规划
38+
39+
###### 1. 划分阶段
40+
41+
按照最长有效括号子串的结束位置进行阶段划分。
42+
43+
###### 2. 定义状态
44+
45+
定义状态 `dp[i]` 表示为:以字符 `s[i]` 为结尾的最长有效括号的长度。
46+
47+
###### 3. 状态转移方程
48+
49+
- 如果 `s[i] == '('`,此时以 `s[i]` 结尾的子串不可能构成有效括号对,则 `dp[i] = 0`
50+
- 如果 `s[i] == ')'`,我们需要考虑 `s[i - 1]` 来判断是否能够构成有效括号对。
51+
- 如果 `s[i - 1] == '('`,字符串形如 `......()`,此时 `s[i - 1]``s[i]``()`,则:
52+
- `dp[i]` 取决于「以字符 `s[i - 2]` 为结尾的最长有效括号长度」 + 「`s[i - 1]``s[i]` 构成的有效括号对长度(`2`)」,即 `dp[i] = dp[i - 2] + 2`
53+
- 特别地,如果 `s[i - 2]` 不存在,即 `i - 2 < 0`,则 `dp[i]` 直接取决于 「`s[i - 1]``s[i]` 构成的有效括号对长度(`2`)」,即 `dp[i] = 2`
54+
- 如果 `s[i - 1] == ')'`,字符串形如 `......))`,此时 `s[i - 1]``s[i]``))`。那么以 `s[i - 1]` 为结尾的最长有效长度为 `dp[i - 1]`,则我们需要看 `i - 1 - dp[i - 1]` 位置上的字符 `s[i - 1 - dp[i - 1]]`是否与 `s[i]` 匹配。
55+
- 如果 `s[i - 1 - dp[i - 1]] == '('`,则说明 `s[i - 1 - dp[i - 1]]``s[i]` 相匹配,此时我们需要看以 `s[i - 1 - dp[i - 1]]` 的前一个字符 `s[i - 1 - dp[i - 2]]` 为结尾的最长括号长度是多少,将其加上 ``s[i - 1 - dp[i - 1]]``s[i]`,从而构成更长的有效括号对:
56+
- `dp[i]` 取决于「以字符 `s[i - 1]` 为结尾的最长括号长度」 + 「以字符 `s[i - 1 - dp[i - 2]]` 为结尾的最长括号长度」+ 「`s[i - 1 - dp[i - 1]]``s[i]` 的长度(`2`)」,即 `dp[i] = dp[i - 1] + dp[i - dp[i - 1] - 2] + 2`
57+
- 特别地,如果 `s[i - dp[i - 1] - 2]` 不存在,即 `i - dp[i - 1] - 2 < 0`,则 `dp[i]` 直接取决于「以字符 `s[i - 1]` 为结尾的最长括号长度」+「`s[i - 1 - dp[i - 1]]``s[i]` 的长度(`2`)」,即 `dp[i] = dp[i - 1] + 2`
58+
59+
###### 4. 初始条件
60+
61+
- 默认所有以字符 `s[i]` 为结尾的最长有效括号的长度为 `0`,即 `dp[i] = 0`
62+
63+
###### 5. 最终结果
64+
65+
根据我们之前定义的状态,`dp[i]` 表示为:以字符 `s[i]` 为结尾的最长有效括号的长度。则最终结果为 `max(dp[i])`
66+
67+
### 思路 1:代码
68+
69+
```Python
70+
class Solution:
71+
def longestValidParentheses(self, s: str) -> int:
72+
dp = [0 for _ in range(len(s))]
73+
ans = 0
74+
for i in range(1, len(s)):
75+
if s[i] == '(':
76+
continue
77+
if s[i - 1] == '(':
78+
if i >= 2:
79+
dp[i] = dp[i - 2] + 2
80+
else:
81+
dp[i] = 2
82+
elif i - dp[i - 1] > 0 and s[i - dp[i - 1] - 1] == '(':
83+
if i - dp[i - 1] >= 2:
84+
dp[i] = dp[i - 1] + dp[i - dp[i - 1] - 2] + 2
85+
else:
86+
dp[i] = dp[i - 1] + 2
87+
ans = max(ans, dp[i])
88+
89+
return ans
90+
```
91+
92+
### 思路 1:复杂度分析
93+
94+
- **时间复杂度**:$O(n),ドル其中 $n$ 为字符串长度。
95+
- **空间复杂度**:$O(n)$。
96+
97+
### 思路 2:栈
98+
99+
1. 定义一个变量 `ans` 用于维护最长有效括号的长度,初始时,`ans = 0`
100+
2. 定义一个栈用于判定括号对是否匹配(栈中存储的是括号的下标),栈底元素始终保持「最长有效括号子串的开始元素的前一个元素下标」。
101+
3. 初始时,我们在栈中存储 `-1` 作为哨兵节点,表示「最长有效括号子串的开始元素的前一个元素下标为 `-1`」,即 `stack = [-1]`,
102+
4. 然后从左至右遍历字符串。
103+
1. 如果遇到左括号,即 `s[i] == '('`,则将其下标 `i` 压入栈,用于后续匹配右括号。
104+
2. 如果遇到右括号,即 `s[i] == ')'`,则将其与最近的左括号进行匹配(即栈顶元素),弹出栈顶元素,与当前右括号进行匹配。弹出之后:
105+
1. 如果栈为空,则说明:
106+
1. 之前弹出的栈顶元素实际上是「最长有效括号子串的开始元素的前一个元素下标」,而不是左括号`(`,此时无法完成合法匹配。
107+
2. 将当前右括号的坐标 `i` 压入栈中,充当「下一个有效括号子串的开始元素前一个下标」。
108+
2. 如果栈不为空,则说明:
109+
1. 之前弹出的栈顶元素为左括号 `(`,此时可完成合法匹配。
110+
2. 当前合法匹配的长度为「当前右括号的下标 `i`」 - 「最长有效括号子串的开始元素的前一个元素下标」。即 `i - stack[-1]`
111+
3. 更新最长匹配长度 `ans``max(ans, i - stack[-1])`
112+
5. 遍历完输出答案 `ans`
113+
114+
### 思路 2:代码
115+
116+
```Python
117+
class Solution:
118+
def longestValidParentheses(self, s: str) -> int:
119+
stack = [-1]
120+
ans = 0
121+
for i in range(len(s)):
122+
if s[i] == '(':
123+
stack.append(i)
124+
else:
125+
stack.pop()
126+
if stack:
127+
ans = max(ans, i - stack[-1])
128+
else:
129+
stack.append(i)
130+
return ans
131+
```
132+
133+
### 思路 2:复杂度分析
134+
135+
- **时间复杂度**:$O(n),ドル其中 $n$ 为字符串长度。
136+
- **空间复杂度**:$O(n)$。
137+
138+
## 参考资料
139+
140+
- 【题解】[动态规划思路详解(C++)——32.最长有效括号](https://leetcode.cn/problems/longest-valid-parentheses/solutions/206995/dong-tai-gui-hua-si-lu-xiang-jie-c-by-zhanganan042/)
141+
- 【题解】[32. 最长有效括号 - 力扣(Leetcode)](https://leetcode.cn/problems/longest-valid-parentheses/solutions/314683/zui-chang-you-xiao-gua-hao-by-leetcode-solution/)
142+
- 【题解】[【Nick~Hot一百题系列】超简单思路栈!](https://leetcode.cn/problems/longest-valid-parentheses/solutions/1258643/nickhotyi-bai-ti-xi-lie-chao-jian-dan-si-ggi4/)

‎Solutions/0232. 用栈实现队列.md‎

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,56 @@
55

66
## 题目大意
77

8-
仅使用两个栈实现先入先出队列。
8+
**要求**:仅使用两个栈实现先入先出队列。
9+
10+
要求实现 `MyQueue` 类:
11+
12+
- `void push(int x)` 将元素 `x` 推到队列的末尾。
13+
- `int pop()` 从队列的开头移除并返回元素。
14+
- `int peek()` 返回队列开头的元素。
15+
- `boolean empty()` 如果队列为空,返回 `True`;否则,返回 `False`
16+
17+
**说明**:
18+
19+
- 只能使用标准的栈操作 —— 也就是只有 `push to top`, `peek / pop from top`, `size`, 和 `is empty` 操作是合法的。
20+
- 可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
21+
- 1ドル <= x <= 9$。
22+
- 最多调用 100ドル$ 次 `push``pop``peek``empty`
23+
- 假设所有操作都是有效的 (例如,一个空的队列不会调用 `pop` 或者 `peek` 操作)。
24+
- 进阶:实现每个操作均摊时间复杂度为 `O(1)` 的队列。换句话说,执行 `n` 个操作的总时间复杂度为 `O(n)`,即使其中一个操作可能花费较长时间。
25+
26+
**示例**:
27+
28+
- 示例 1:
29+
30+
```Python
31+
输入:
32+
["MyQueue", "push", "push", "peek", "pop", "empty"]
33+
[[], [1], [2], [], [], []]
34+
输出:
35+
[null, null, null, 1, 1, false]
36+
37+
解释:
38+
MyQueue myQueue = new MyQueue();
39+
myQueue.push(1); // queue is: [1]
40+
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
41+
myQueue.peek(); // return 1
42+
myQueue.pop(); // return 1, queue is [2]
43+
myQueue.empty(); // return false
44+
```
945

1046
## 解题思路
1147

12-
使用两个栈,inStack 用于输入,outStack 用于输出。
48+
### 思路 1:双栈
1349

14-
- push 操作:将元素压入 inStack 中
15-
- pop 操作:如果 outStack 输出栈为空,将 inStack 输入栈元素依次取出,按顺序压入 outStack 栈。这样 outStack 栈的元素顺序和之前 inStack 元素顺序相反,outStack 顶层元素就是要取出的队头元素,将其移出,并返回该元素。如果 outStack 输出栈不为空,则直接取出顶层元素。
16-
- peek 操作:和 pop 操作类似,只不过最后一步不需要取出顶层元素,直接将其返回即可。
17-
- empty 操作:如果 inStack 和 outStack 都为空,则队列为空,否则队列不为空。
50+
使用两个栈,`inStack` 用于输入,`outStack` 用于输出。
1851

19-
## 代码
52+
- `push` 操作:将元素压入 `inStack` 中。
53+
- `pop` 操作:如果 `outStack` 输出栈为空,将 `inStack` 输入栈元素依次取出,按顺序压入 `outStack` 栈。这样 `outStack` 栈的元素顺序和之前 `inStack` 元素顺序相反,`outStack` 顶层元素就是要取出的队头元素,将其移出,并返回该元素。如果 `outStack` 输出栈不为空,则直接取出顶层元素。
54+
- `peek` 操作:和 `pop` 操作类似,只不过最后一步不需要取出顶层元素,直接将其返回即可。
55+
- `empty` 操作:如果 `inStack``outStack` 都为空,则队列为空,否则队列不为空。
56+
57+
### 思路 1:代码
2058

2159
```Python
2260
class MyQueue:
@@ -68,3 +106,8 @@ class MyQueue:
68106
"""
69107
```
70108

109+
### 思路 1:复杂度分析
110+
111+
- **时间复杂度**:`push``empty` 为 $O(1),ドル`pop``peek` 为均摊 $O(1)$。
112+
- **空间复杂度**:$O(n)$。
113+

‎Solutions/0678. 有效的括号字符串.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
###### 3. 状态转移方程
4444

45-
长度大于 `2`时,我们需要根据 `s[i]``s[j]` 的情况,以及子串中间的有效字符串情况来判断 `dp[i][j]`
45+
长度大于 `2`时,我们需要根据 `s[i]``s[j]` 的情况,以及子串中间的有效字符串情况来判断 `dp[i][j]`
4646

4747
- 如果 `s[i]``s[j]` 分别表示左括号和右括号,或者为 `'*'`(此时 `s[i]``s[j]` 可以分别看做是左括号、右括号)。则如果 `dp[i + 1][j - 1] == True` 时,`dp[i][j] = True`
4848
- 如果可以将从下标 `i` 到下标 `j` 的子串从中间分开为两个有效字符串,则 `dp[i][j] = True`。即如果存在 $i \le k < j,ドル使得 `dp[i][k] == True` 并且 `dp[k + 1][j] == True`,则 `dp[i][j] = True`
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# [1903. 字符串中的最大奇数](https://leetcode.cn/problems/largest-odd-number-in-string/)
2+
3+
- 标签:贪心 、数学、字符串
4+
- 难度:简单
5+
6+
## 题目大意
7+
8+
**描述**:给定一个字符串 `num`,表示一个大整数。
9+
10+
**要求**:在字符串 `num` 的所有非空子字符串中找出值最大的奇数,并以字符串形式返回。如果不存在奇数,则返回一个空字符串 `""`
11+
12+
**说明**:
13+
14+
- **子字符串**:指的是字符串中一个连续的字符序列。
15+
- 1ドル \le num.length \le 10^5$
16+
- `num` 仅由数字组成且不含前导零。
17+
18+
**示例**:
19+
20+
- 示例 1:
21+
22+
```Python
23+
输入:num = "52"
24+
输出:"5"
25+
解释:非空子字符串仅有 "5""2""52""5" 是其中唯一的奇数。
26+
```
27+
28+
- 示例 2:
29+
30+
```Python
31+
输入:num = "4206"
32+
输出:""
33+
解释:在 "4206" 中不存在奇数。
34+
```
35+
36+
## 解题思路
37+
38+
### 思路 1:贪心算法
39+
40+
1.
41+
42+
### 思路 1:代码
43+
44+
```Python
45+
class Solution:
46+
def largestOddNumber(self, num: str) -> str:
47+
for i in range(len(num) - 1, -1, -1):
48+
if int(num[i]) % 2 == 1:
49+
return num[0: i + 1]
50+
return ""
51+
```
52+
53+
### 思路 1:复杂度分析
54+
55+
- **时间复杂度**:$O(n)$。
56+
- **空间复杂度**:$O(1)$。

0 commit comments

Comments
(0)

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