Skip to content

Commit 271b77d

Browse files
Merge pull request #786 from SharingSource/ac_oier
✨feat: add 10、1035、1137、1143、260、32、384、44、524、590、82、83、88
2 parents 27406b2 + 1c3b609 commit 271b77d

15 files changed

+1255
-225
lines changed

Index/括号问题.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
33
| [20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/valid-parentheses/solution/shua-chuan-lc-zhan-ascii-chai-zhi-jie-fa-00zo/) | 简单 | 🤩🤩🤩🤩🤩 |
44
| [22. 括号生成](https://leetcode-cn.com/problems/generate-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/generate-parentheses/solution/shua-chuan-lc-dfs-jie-fa-by-ac_oier-nknl/) | 中等 | 🤩🤩🤩🤩 |
5-
| [32. 最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-valid-parentheses/solution/shua-chuan-lc-miao-dong-xi-lie-shi-yong-95ezk/) | 困难 | 🤩🤩🤩🤩 |
5+
| [32. 最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses/) | [LeetCode 题解链接](https://leetcode.cn/problems/longest-valid-parentheses/solutions/577327/shua-chuan-lc-miao-dong-xi-lie-shi-yong-95ezk/) | 困难 | 🤩🤩🤩🤩 |
66
| [301. 删除无效的括号](https://leetcode-cn.com/problems/remove-invalid-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/remove-invalid-parentheses/solution/yi-fen-zhong-nei-kan-dong-jiang-gua-hao-aya6k/) | 困难 | 🤩🤩🤩🤩 |
77
| [678. 有效的括号字符串](https://leetcode-cn.com/problems/valid-parenthesis-string/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/valid-parenthesis-string/solution/gong-shui-san-xie-yi-ti-shuang-jie-dong-801rq/) | 中等 | 🤩🤩🤩🤩🤩 |
88

Index/栈.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
| 题目 | 题解 | 难度 | 推荐指数 |
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
33
| [20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/valid-parentheses/solution/shua-chuan-lc-zhan-ascii-chai-zhi-jie-fa-00zo/) | 简单 | 🤩🤩🤩🤩🤩 |
4-
| [32. 最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-valid-parentheses/solution/shua-chuan-lc-miao-dong-xi-lie-shi-yong-95ezk/) | 困难 | 🤩🤩🤩🤩 |
4+
| [32. 最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses/) | [LeetCode 题解链接](https://leetcode.cn/problems/longest-valid-parentheses/solutions/577327/shua-chuan-lc-miao-dong-xi-lie-shi-yong-95ezk/) | 困难 | 🤩🤩🤩🤩 |
55
| [71. 简化路径](https://leetcode-cn.com/problems/simplify-path/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/simplify-path/solution/gong-shui-san-xie-jian-dan-zi-fu-chuan-m-w7xi/) | 中等 | 🤩🤩🤩🤩 |
66
| [155. 最小栈](https://leetcode-cn.com/problems/min-stack/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/min-stack/solution/tu-li-zhan-shi-shuang-zhan-shi-xian-zui-fcwj5/) | 简单 | 🤩🤩🤩🤩🤩 |
77
| [232. 用栈实现队列](https://leetcode-cn.com/problems/implement-queue-using-stacks/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/implement-queue-using-stacks/solution/sha-shi-jun-tan-fu-za-du-ya-wo-de-suan-f-gb6d/) | 简单 | 🤩🤩🤩🤩🤩 |

LeetCode/1-10/10. 正则表达式匹配(困难).md

+23-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
这是 LeetCode 上的 **[10. 正则表达式匹配](https://leetcode-cn.com/problems/regular-expression-matching/solution/shua-chuan-lc-dong-tai-gui-hua-jie-fa-by-zn9w/)** ,难度为 **困难**
44

5-
Tag : 「动态规划」
5+
Tag : 「动态规划」、「序列 DP」
66

77

88

@@ -11,35 +11,44 @@ Tag : 「动态规划」
1111
* `'.'` 匹配任意单个字符
1212
* `'*'` 匹配零个或多个前面的那一个元素
1313

14-
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
14+
所谓匹配,是要涵盖整个字符串 `s`,而不是部分字符串。
1515

1616
示例 1:
1717
```
1818
输入:s = "aa" p = "a"
19+
1920
输出:false
21+
2022
解释:"a" 无法匹配 "aa" 整个字符串。
2123
```
2224
示例 2:
2325
```
2426
输入:s = "aa" p = "a*"
27+
2528
输出:true
29+
2630
解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
2731
```
2832
示例 3:
2933
```
3034
输入:s = "ab" p = ".*"
35+
3136
输出:true
37+
3238
解释:".*" 表示可匹配零个或多个('*')任意字符('.')。
3339
```
3440
示例 4:
3541
```
3642
输入:s = "aab" p = "c*a*b"
43+
3744
输出:true
45+
3846
解释:因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
3947
```
4048
示例 5:
4149
```
4250
输入:s = "mississippi" p = "mis*is*p*."
51+
4352
输出:false
4453
```
4554

@@ -60,25 +69,29 @@ Tag : 「动态规划」
6069
* `'.'`:能够匹配 `s` 中同一位置的任意字符
6170
* `'*'`:不能够单独使用 `'*'`,必须和前一个字符同时搭配使用,数据保证了 `'*'` 能够找到前面一个字符。能够匹配 `s` 中同一位置字符任意次。
6271

63-
所以本题关键是分析当出现 `a*` 这种字符时,是匹配 0a、还是 1a、还是 2a ...
72+
所以本题关键是分析当出现 `a*` 这种字符时,是匹配 $0$`a`、还是 $1$`a`、还是 $2$`a` ...
6473

6574
本题可以使用动态规划进行求解:
6675

67-
* 状态定义:`f(i,j)` 代表考虑 `s` 中以 `i` 为结尾的子串和 `p` 中的 `j` 为结尾的子串是否匹配。即最终我们要求的结果为 `f[n][m]`
76+
* 状态定义:`f(i,j)` 代表考虑 `s` 中以 `i` 为结尾的子串和 `p` 中的 `j` 为结尾的子串是否匹配。最终我们要求的结果为 `f[n][m]`
6877

6978
* 状态转移:也就是我们要考虑 `f(i,j)` 如何求得,前面说到了 `p` 有三种字符,所以这里的状态转移也要分三种情况讨论:
7079

71-
1. `p[j]` 为普通字符:匹配的条件是前面的字符匹配,同时 `s` 中的第 `i` 个字符和 `p` 中的第 `j` 位相同。 `f(i,j) = f(i - 1, j - 1) && s[i] == p[j]`
80+
1. `p[j]` 为普通字符:匹配的条件是前面的字符匹配,同时 `s` 中的第 `i` 个字符和 `p` 中的第 `j` 位相同。
7281

73-
2. `p[j]``'.'`:匹配的条件是前面的字符匹配, `s` 中的第 `i` 个字符可以是任意字符。即 `f(i,j) = f(i - 1, j - 1) && p[j] == '.'`
82+
`f(i,j) = f(i - 1, j - 1) && s[i] == p[j]`
7483

75-
3. `p[j]` 为 `'*'`:读得 `p[j - 1]` 的字符,例如为字符 a。 然后根据 `a*` 实际匹配 `s` 中 `a` 的个数是 0 个、1 个、2 个 ...
84+
2. `p[j]` 为 `'.'`:匹配的条件是前面的字符匹配, `s` 中的第 `i` 个字符可以是任意字符。
7685

77-
3.1. 当匹配为 0 个:`f(i,j) = f(i, j - 2)`
86+
`f(i,j) = f(i - 1, j - 1) && p[j] == '.'`。
7887

79-
3.2. 当匹配为 1 个:`f(i,j) = f(i - 1, j - 2) && (s[i] == p[j - 1] || p[j - 1] == '.')`
88+
3. `p[j]``'*'`:读得 `p[j - 1]` 的字符,例如为字符 `a`。 然后根据 `a*` 实际匹配 `s``a` 的个数是 $0$ 个、$1$ 个、$2$ 个 ...
8089

81-
3.3. 当匹配为 2 个:`f(i,j) = f(i - 2, j - 2) && ((s[i] == p[j - 1] && s[i - 1] == p[j - 1]) || p[j] == '.')`
90+
3.1. 当匹配为 $0$ 个:`f(i,j) = f(i, j - 2)`
91+
92+
3.2. 当匹配为 $1$ 个:`f(i,j) = f(i - 1, j - 2) && (s[i] == p[j - 1] || p[j - 1] == '.')`
93+
94+
3.3. 当匹配为 $2$ 个:`f(i,j) = f(i - 2, j - 2) && ((s[i] == p[j - 1] && s[i - 1] == p[j - 1]) || p[j] == '.')`
8295

8396
**我们知道,通过「枚举」来确定 `*` 到底匹配多少个 `a` 这样的做法,算法复杂度是很高的。**
8497

LeetCode/1031-1040/1035. 不相交的线(中等).md

+61-15
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ Tag : 「最长公共子序列」、「序列 DP」、「LCS」
66

77

88

9-
在两条独立的水平线上按给定的顺序写下 nums1nums2 中的整数。
9+
在两条独立的水平线上按给定的顺序写下 `s1``s2` 中的整数。
1010

11-
现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足:
11+
现在,可以绘制一些连接两个数字 $s1[i]$ 和 $s2[j]$ 的直线,这些直线需要同时满足满足:
1212

13-
* nums1[i] == nums2[j]
13+
* $s1[i] = s2[j]$
1414
* 且绘制的直线不与任何其他连线(非水平线)相交。
1515

1616
请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。
@@ -24,39 +24,37 @@ Tag : 「最长公共子序列」、「序列 DP」、「LCS」
2424
<img src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2019/04/28/142.png" style="zoom:18%;" />
2525

2626
```
27-
输入:nums1 = [1,4,2], nums2 = [1,2,4]
27+
输入:s1 = [1,4,2], s2 = [1,2,4]
2828
2929
输出:2
3030
3131
解释:可以画出两条不交叉的线,如上图所示。
32-
但无法画出第三条不相交的直线,因为从 nums1[1]=4 到 nums2[2]=4 的直线将与从 nums1[2]=2 到 nums2[1]=2 的直线相交。
32+
但无法画出第三条不相交的直线,因为从 s1[1]=4 到 s2[2]=4 的直线将与从 s1[2]=2 到 s2[1]=2 的直线相交。
3333
```
3434
示例 2:
3535
```
36-
输入:nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
36+
输入:s1 = [2,5,1,2,5], s2 = [10,5,2,1,5,2]
3737
3838
输出:3
3939
```
4040
示例 3:
4141
```
42-
输入:nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]
42+
输入:s1 = [1,3,7,1,7,5], s2 = [1,9,2,5,1]
4343
4444
输出:2
4545
```
4646

4747
提示:
48-
* 1 <= nums1.length <= 500
49-
* 1 <= nums2.length <= 500
50-
* 1 <= nums1[i], nums2[i] <= 2000
48+
* $1 <= s1.length <= 500$
49+
* $1 <= s2.length <= 500$
50+
* $1 <= s1[i], s2[i] <= 2000$
5151

5252
---
5353

5454
### 动态规划
5555

5656
这是一道「[最长公共子序列(LCS)](https://leetcode-cn.com/problems/longest-common-subsequence/solution/gong-shui-san-xie-zui-chang-gong-gong-zi-xq0h/)」的轻度变形题。
5757

58-
为了让你更好的与「[最长公共子序列(LCS)](https://leetcode-cn.com/problems/longest-common-subsequence/solution/gong-shui-san-xie-zui-chang-gong-gong-zi-xq0h/)」裸题进行对比,我们使用 $s1$ 代指 $nums1$,$s2$ 代指 $nums2$。
59-
6058
对于这类题都使用如下「状态定义」即可:
6159

6260
**$f[i][j]$ 代表考虑 $s1$ 的前 $i$ 个字符、考虑 $s2$ 的前 $j$ 的字符,形成的最长公共子序列长度。**
@@ -87,7 +85,7 @@ $$
8785

8886
上述分析过程建议加深理解,估计很多同学能 AC 但其实并不知道 LCS 问题的状态转移是包含了「重复状态比较」的。
8987

90-
代码:
88+
Java 代码:
9189
```Java
9290
class Solution {
9391
public int maxUncrossedLines(int[] s1, int[] s2) {
@@ -105,8 +103,56 @@ class Solution {
105103
}
106104
}
107105
```
108-
* 时间复杂度:$O(n * m)$
109-
* 空间复杂度:$O(n * m)$
106+
C++ 代码:
107+
```C++
108+
class Solution {
109+
public:
110+
int maxUncrossedLines(vector<int>& s1, vector<int>& s2) {
111+
int n = s1.size(), m = s2.size();
112+
vector<vector<int>> f(n + 1, vector<int>(m + 1, 0));
113+
for (int i = 1; i <= n; ++i) {
114+
for (int j = 1; j <= m; ++j) {
115+
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
116+
if (s1[i - 1] == s2[j - 1]) {
117+
f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1);
118+
}
119+
}
120+
}
121+
return f[n][m];
122+
}
123+
};
124+
```
125+
Python 代码:
126+
```Python
127+
class Solution:
128+
def maxUncrossedLines(self, s1: List[int], s2: List[int]) -> int:
129+
n, m = len(s1), len(s2)
130+
f = [[0] * (m + 1) for _ in range(n + 1)]
131+
for i in range(1, n + 1):
132+
for j in range(1, m + 1):
133+
f[i][j] = max(f[i - 1][j], f[i][j - 1])
134+
if s1[i - 1] == s2[j - 1]:
135+
f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1)
136+
return f[n][m]
137+
```
138+
TypeScript 代码:
139+
```TypeScript
140+
function maxUncrossedLines(s1: number[], s2: number[]): number {
141+
const n = s1.length, m = s2.length;
142+
const f = Array.from({ length: n + 1 }, () => Array(m + 1).fill(0));
143+
for (let i = 1; i <= n; ++i) {
144+
for (let j = 1; j <= m; ++j) {
145+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
146+
if (s1[i - 1] === s2[j - 1]) {
147+
f[i][j] = Math.max(f[i][j], f[i - 1][j - 1] + 1);
148+
}
149+
}
150+
}
151+
return f[n][m];
152+
};
153+
```
154+
* 时间复杂度:$O(n \times m)$
155+
* 空间复杂度:$O(n \times m)$
110156

111157
---
112158

0 commit comments

Comments
 (0)