Skip to content

Commit 2b74951

Browse files
author
luzhipeng
committed
2 parents d256f92 + 5771a93 commit 2b74951

10 files changed

+558
-15
lines changed

README.en.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,13 @@ The data structures mainly includes:
184184

185185
#### Hard
186186
- [0023.merge-k-sorted-lists](./problems/23.merge-k-sorted-lists.md)
187+
- [0032.longest-valid-parentheses](./problems/32.longest-valid-parentheses.md) 🆕
187188
- [0042.trapping-rain-water](./problems/42.trapping-rain-water.md)
188-
- [0128.longest-consecutive-sequence](./problems/128.longest-consecutive-sequence.md) 🆕
189+
- [0128.longest-consecutive-sequence](./problems/128.longest-consecutive-sequence.md) 🆕
189190
- [0145.binary-tree-postorder-traversal](./problems/145.binary-tree-postorder-traversal.md)
190191
- [0146.lru-cache](./problems/146.lru-cache.md)
191192
- [0239.sliding-window-maximum](./problems/239.sliding-window-maximum.md)
192-
- [0295.find-median-from-data-stream](./problems/295.find-median-from-data-stream.md) 🆕
193+
- [0295.find-median-from-data-stream](./problems/295.find-median-from-data-stream.md) 🆕
193194
- [0301.remove-invalid-parentheses](./problems/301.remove-invalid-parentheses.md)
194195

195196

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,13 @@ leetcode 题解,记录自己的 leetcode 解题之路。
182182

183183
#### 困难难度
184184
- [0023.merge-k-sorted-lists](./problems/23.merge-k-sorted-lists.md)
185+
- [0032.longest-valid-parentheses](./problems/32.longest-valid-parentheses.md) 🆕
185186
- [0042.trapping-rain-water](./problems/42.trapping-rain-water.md)
186-
- [0128.longest-consecutive-sequence](./problems/128.longest-consecutive-sequence.md) 🆕
187+
- [0128.longest-consecutive-sequence](./problems/128.longest-consecutive-sequence.md) 🆕
187188
- [0145.binary-tree-postorder-traversal](./problems/145.binary-tree-postorder-traversal.md)
188189
- [0146.lru-cache](./problems/146.lru-cache.md)
189190
- [0239.sliding-window-maximum](./problems/239.sliding-window-maximum.md)
190-
- [0295.find-median-from-data-stream](./problems/295.find-median-from-data-stream.md) 🆕
191+
- [0295.find-median-from-data-stream](./problems/295.find-median-from-data-stream.md) 🆕
191192
- [0301.remove-invalid-parentheses](./problems/301.remove-invalid-parentheses.md)
192193

193194
### 数据结构与算法的总结
@@ -253,4 +254,4 @@ http://t.me/leetcode_intl
253254

254255
- 如果有想法和创意,请提[issue](https://github.com/azl397985856/leetcode/issues)或者进群提
255256
- 如果想贡献代码,请提[PR](https://github.com/azl397985856/leetcode/pulls)
256-
- 如果需要修改项目中图片,[这里](./assets/drawio/)存放了项目中绘制图的源代码, 大家可以用[draw.io](https://www.draw.io/)打开进行编辑。
257+
- 如果需要修改项目中图片,[这里](./assets/drawio/)存放了项目中绘制图的源代码, 大家可以用[draw.io](https://www.draw.io/)打开进行编辑。
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile modified="2019-06-04T13:25:22.060Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" etag="8H9UqhbsuCS1_Zfojrgc" version="10.7.4" type="device"><diagram id="oSH-UZAoREgWgg9KTufO" name="Page-1">7Z1db6M4FIZ/jTU7F13xHXOZr3alnVlp1YuZnTua0CSzacgQOm33168NNhBMUjqNOTYgVSoYMI4fH9vv4RiQPX14vomD/fpztAy3yDKWz8ieIcsyTReTfzTlJUtxPS9LWMWbJTupSLjd/BeyRIOlPm6W4eHoxCSKtslmf5y4iHa7cJEcpQVxHD0dn3YfbY/vug9WoZBwuwi2YuqXzTJZZ6nYNYr0P8LNas3vbBrsyEPAT2YJh3WwjJ5KSfYc2dM4ipJs6+F5Gm5p5fF6ya67PnE0L1gc7pImF6yC73fO/ttff45//P0UWMZ8/eBfsVx+BttH9oOR5W1JfpP7iGRLSp28sKrwfjxG/MDVIQU1JidYzv65OEi2VvT/bzwbUp4spyydVUWeqRVHj7tlSItokMNP600S3u6DBT36RFoUSVsnD1uyZ+ZXl38yL38YJ+FzKYlVwU0YPYRJ/EJOYUctzoe1R8x2nwq4Dktal7jytIA1p1WecVHjZINV+hsAWJIAfFQWgKMWALt3ALBaAJy+dUG2pRYAr28ATE8tAKO+dUGOYoMw7hsAWzELMGVNgwxVCVTnoXmfBIZA1kRIXQSOaghkTYXURYBVQ+D2DUF1NgqPQNZ0SA6C+812O422UZxea9/fh95iQdIPSRz9G5aOLEf+nWHImcHCQ5M1hVLWbqpzWHgEft8QVGex4Ah4V6oJApiuS7XxxpLlA+8QtKpayWmAQZMlGK0OQXNUg9Y/iYlVQ9A7iVnVN/AIZPnbOzTeVPUNPDS9ROkFEFT1DTyC3knMqr6BR6CXxFRC34BDswdR+vo8rdLZ5ZMGMGiyRGmH9Q08NFmi1OkQNKwaNL1EKQi0qoaCh6bXYzolNBQ8NL2E7wUQVDUUPILeydiqhoJHoJeMVUJDwUMbhO/rM7tqZwf9YI9nPGioN2gocGiyhG+XNRQ4NFnCt0Pdo6ChwKHp9ShQDQ0FDk0v4XsBBIKGAkcgS8Z63bEbQXWBQ9NL+KqhusCh6SWVLzGzqwYVQwtfRy/hewkE1VVB0Aj4qyZ6hKC6KggcgV4hwpcYwKtR2uAI9HpMd4nhuLq6ARyBXoLxAgiENT7gCHon/4Q1PuAI9HqKqYSSgIc2yL/XZ13VgF8DGlr/5F91xQ44gv7Jv+qKHWgEfPzrDwJhxQ44AksrBEo8KYGH1jvBKKzYAUfQO8EorNgBR6CXYFRCrcBDGyTm6/O0amcH/Qo7T5bEtDoErapvwKHJkpgdjjaDh9Y7USooImgEI70eiKmhiMCh6SVjL4BAUETgCHonSgVFBI5AL1GqhiKChubrZTdKKCIHWsb6siytw4oIHposh1GHFRE8tMFh9PpExFINml6Pt5XQUPDQ9PI9gECrqi5waPk3+YYlO82FmgLUBifT6x2kaqOayT/lU6rGcLkKb9luFCfraBXtgu28SJ0cV3Rxzqco2rPq/R4myQv7PmjwmETHlR8+b5Kvpe1/aFa/u2xv9sxyTnde+M6O/OCv5Z3SVXS3uCzd49edxHaIHuNFeLZJs8pJgngVJmfOZBM6WnNnm0EcboNk8zM8KocEU5TlOjyo6req6DJoB4jJP880mFVd87QbmpWrml3J8mst9zyfu7iwKS1MDTxY3OTf4Rpsra7JOg1tjWNUxtZkuSN1tjXoJd4m/+DaYGt1TdZtOl10FbM1WV5kjW0NPKzQNL3B1k43Wa/puOYrZmuynP862xr0S/dN/hXLwdbqmuyooa3xYA1lbE1WkK/OtgbvG8GDrZ1usrihrfEXEytja7Kej2psa+AvQjb5V2YHW6trsn5DW+Ovo1PG1mQ91tbZ1sB9I9zYB1ur64iMhraWP0dWxdh4yQdjQyDPrV+m4VNw5bx8cW4+zb8d/NkcJ1dirMEmrQuLZGeguYswRv6MboxHCE/SlCnyPVLn7mSDXHLIQROMJuP8GozGJhpjNB+hMTk2Tjf8dIPkMkP+KE2ZorHHL7Zoij9G2EFzD/lTRObWcx/5Lppc8xQ/3UgLRDZIUUgOtDTXaDJKcyYbfukql96xuMXYqGskJ1uD2U5raPLGP9xme7Bq24OZsT1Q5qTJlKh/+O0D5+4hUseTFBOeofE8r++8uglkgpGeQuDMETatkpkWp+X5vQF7Whw8Y4dIImmG2EaTrKTkKpeWlBSAbPt2WgCDliG/F7kRbXTs5NrmrX7zqRu6W20+p5/rHvbB7te7eLPUULKcJIQuLYMQ39eGLnkLHN7dXwaauF4BdgTQerVCS8iEURsWmaynTHaHkAlrFWCRyXpY0cryknaQiSsVYJGd9sO9bywzujOWiesUYJHJcue0Eu/eDjJxlQIsMmleAbc7zMQ1CrDM+Aefu+ugow2GFcT0mjrs6ts3O7Hsrzs33LTvrTtb7JNmeexma2qqplUfDU+FuYPGVirMp1TvnzJebR19wCbb+Tj6C5qs1dBk4UJ9z5b70jZrnnC6d99ooa3WPK30NfCnhebSDUd1kyPfG9nBWSN9hwYBhyZL67fiUWsHmuAEBYcmK8KtFZ9aS9CU6x61fo1lS9CqjlBwaLKcNKPuQBOcNNDQ+ExXT2doSxORqv8aHJqsF0m04g5tB5rgWgOH9pqIU9of2hI05Syt5iE6jSm5pn9zTOORJgYLJRnPsqCTTR5akklpFv4kamoeicUiXdK4Jt/JL6lznvGcabAOuz6LuJryu45PRWP5yL8WY7hKkT8XDoNJ3Tbs2ny/iRvn18Nk6hZutBtkJcp6GmVlFax9A+FpEXnlBQ+02nZ3B/qvFOSUxlH5o+NwpQyhRnFLtUtE2yUianZa+/bpuLeP74l7K4tCIe7N5wGQmNokNku279EN3ymXh7QVi7SVLMm6ylpCdsydlcI4Z4hI0XR4oKda1WvN47PJXcy02PO04/KQj9P25iPssjA7ViTecaXNtNrQWPyoX7RPe1YuoTWxmkfgWe+ocOdtFZ4GGpKulG7MSWHORa6mmRSlpUPTJG1BLPGqOHauitOfTWuW1bWlg93Wjbvt2q3otqF26wx2O9jtYLcn7RZ+BiR67qjdun2dAdUucGyXiOiWo7XvdbUndavXOkNPCtuTZik4/7WeDnYLv+JC9MxSux31tSetXVHXLpEat2uxqi1dgUS6hLIZlGr/3evfckfSyYVwOthVrUfvQhTJbhxR12h+7Ib8pPXnaBnSM/4H</diagram></mxfile>
Loading

problems/102.binary-tree-level-order-traversal.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ return its level order traversal as:
3030

3131
然后不断的出队, 如果出队的是null,则表式这一层已经结束了,我们就继续push一个null。
3232

33+
如果不入队特殊元素Null来表示每层的结束,则在while循环开始时保存当前队列的长度,以保证每次只遍历一层(参考下面的C++ Code)。
34+
35+
> 如果采用递归方式,则需要将当前节点,当前所在的level以及结果数组传递给递归函数。在递归函数中,取出节点的值,添加到level参数对应结果数组元素中(参考下面的C++ Code)。
36+
3337

3438
## 关键点解析
3539

@@ -43,7 +47,9 @@ return its level order traversal as:
4347

4448

4549
## 代码
50+
* 语言支持:JS,C++
4651

52+
Javascript Code:
4753
```js
4854
/*
4955
* @lc app=leetcode id=102 lang=javascript
@@ -123,7 +129,66 @@ var levelOrder = function(root) {
123129

124130
return items;
125131
};
132+
133+
```
134+
C++ Code:
135+
```C++
136+
/**
137+
* Definition for a binary tree node.
138+
* struct TreeNode {
139+
* int val;
140+
* TreeNode *left;
141+
* TreeNode *right;
142+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
143+
* };
144+
*/
145+
146+
// 迭代
147+
class Solution {
148+
public:
149+
vector<vector<int>> levelOrder(TreeNode* root) {
150+
auto ret = vector<vector<int>>();
151+
if (root == nullptr) return ret;
152+
auto q = vector<TreeNode*>();
153+
q.push_back(root);
154+
auto level = 0;
155+
while (!q.empty())
156+
{
157+
auto sz = q.size();
158+
ret.push_back(vector<int>());
159+
for (auto i = 0; i < sz; ++i)
160+
{
161+
auto t = q.front();
162+
q.erase(q.begin());
163+
ret[level].push_back(t->val);
164+
if (t->left != nullptr) q.push_back(t->left);
165+
if (t->right != nullptr) q.push_back(t->right);
166+
}
167+
++level;
168+
}
169+
return ret;
170+
}
171+
};
172+
173+
// 递归
174+
class Solution {
175+
public:
176+
vector<vector<int>> levelOrder(TreeNode* root) {
177+
vector<vector<int>> v;
178+
levelOrder(root, 0, v);
179+
return v;
180+
}
181+
private:
182+
void levelOrder(TreeNode* root, int level, vector<vector<int>>& v) {
183+
if (root == NULL) return;
184+
if (v.size() < level + 1) v.resize(level + 1);
185+
v[level].push_back(root->val);
186+
levelOrder(root->left, level + 1, v);
187+
levelOrder(root->right, level + 1, v);
188+
}
189+
};
126190
```
191+
127192
## 相关题目
128193
- [103.binary-tree-zigzag-level-order-traversal](./103.binary-tree-zigzag-level-order-traversal.md)
129194
- [104.maximum-depth-of-binary-tree](./104.maximum-depth-of-binary-tree.md)

problems/104.maximum-depth-of-binary-tree.md

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@ var maxDepth = function(root) {
4444

4545
- 队列
4646

47-
- 队列中用 Null(一个特殊元素)来划分每层
47+
- 队列中用 Null(一个特殊元素)来划分每层,或者在对每层进行迭代之前保存当前队列元素的个数(即当前层所含元素个数)
4848

4949
- 树的基本操作- 遍历 - 层次遍历(BFS)
5050

5151
## 代码
52+
* 语言支持:JS,C++
5253

54+
JavaScript Code:
5355
```js
5456
/*
5557
* @lc app=leetcode id=104 lang=javascript
@@ -94,6 +96,40 @@ var maxDepth = function(root) {
9496
return depth;
9597
};
9698
```
99+
C++ Code:
100+
```C++
101+
/**
102+
* Definition for a binary tree node.
103+
* struct TreeNode {
104+
* int val;
105+
* TreeNode *left;
106+
* TreeNode *right;
107+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
108+
* };
109+
*/
110+
class Solution {
111+
public:
112+
int maxDepth(TreeNode* root) {
113+
if (root == nullptr) return 0;
114+
auto q = vector<TreeNode*>();
115+
auto d = 0;
116+
q.push_back(root);
117+
while (!q.empty())
118+
{
119+
++d;
120+
auto sz = q.size();
121+
for (auto i = 0; i < sz; ++i)
122+
{
123+
auto t = q.front();
124+
q.erase(q.begin());
125+
if (t->left != nullptr) q.push_back(t->left);
126+
if (t->right != nullptr) q.push_back(t->right);
127+
}
128+
}
129+
return d;
130+
}
131+
};
132+
```
97133
## 相关题目
98134
- [102.binary-tree-level-order-traversal](./102.binary-tree-level-order-traversal.md)
99-
- [103.binary-tree-zigzag-level-order-traversal](./103.binary-tree-zigzag-level-order-traversal.md)
135+
- [103.binary-tree-zigzag-level-order-traversal](./103.binary-tree-zigzag-level-order-traversal.md)

problems/11.container-with-most-water.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ eg:
6666

6767

6868
## 代码
69+
* 语言支持:JS,C++
70+
71+
JavaScript Code:
6972

7073
```js
7174
/*
@@ -135,4 +138,19 @@ var maxArea = function(height) {
135138
return max;
136139
};
137140
```
138-
141+
C++ Code:
142+
```C++
143+
class Solution {
144+
public:
145+
int maxArea(vector<int>& height) {
146+
auto ret = 0ul, leftPos = 0ul, rightPos = height.size() - 1;
147+
while( leftPos < rightPos)
148+
{
149+
ret = std::max(ret, std::min(height[leftPos], height[rightPos]) * (rightPos - leftPos));
150+
if (height[leftPos] < height[rightPos]) ++leftPos;
151+
else --rightPos;
152+
}
153+
return ret;
154+
}
155+
};
156+
```
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
## 题目地址
2+
https://leetcode.com/problems/longest-valid-parentheses/
3+
4+
## 题目描述
5+
6+
```
7+
Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
8+
9+
Example 1:
10+
11+
Input: "(()"
12+
Output: 2
13+
Explanation: The longest valid parentheses substring is "()"
14+
Example 2:
15+
16+
Input: ")()())"
17+
Output: 4
18+
Explanation: The longest valid parentheses substring is "()()"
19+
```
20+
21+
## 思路(动态规划)
22+
23+
所有的动态规划问题, 首先需要解决的就是如何寻找合适的子问题.
24+
该题需要我们找到最长的有效括号对, 我们首先想到的就是定义**dp[i]为前i个字符串的最长有效括号对长度**, 但是随后我们会发现, 这样的定义, 我们无法找到dp[i]和dp[i-1]的任何关系.
25+
所以, 我们需要重新找一个新的定义: 定义**dp[i]为以第i个字符结尾的最长有效括号对长度**. 然后, 我们通过下面这个例子找一下dp[i]和dp[i-1]之间的关系.
26+
27+
```python
28+
s = '(())())'
29+
```
30+
31+
从上面的例子我们可以观察出一下几点结论(**描述中i为图中的dp数组的下标, 对应s的下标应为i-1, 第i个字符的i从1开始**).
32+
1. base case: 空字符串的最长有效括号对长度肯定为0, 即: dp[0] = 0;
33+
2. s的第**1**个字符结尾的最长有效括号对长度为0, s的第**2**个字符结尾的最长有效括号对长度也为0, 这个时候我们可以得出结论: 最长有效括号对不可能以'('结尾, 即: dp[1] = d[2] = 0;
34+
3. 当i等于3时, 我们可以看出dp[2]=0, dp[3]=2, 因为第2个字符(**s[1]**)和第3个字符(**s[2]**)是配对的;
35+
当i等于4时, 我们可以看出dp[3]=2, dp[4]=4, 因为我们配对的是第1个字符(**s[0]**)和第4个字符(**s[3]**);
36+
因此, 我们可以得出结论: 如果第**i**个字符和第<strong>i-1-dp[i-1]</strong>个字符是配对的, 则dp[i] = dp[i-1] + 2, 其中: i-1-dp[i-1] >= 1, 因为第0个字符没有任何意义;
37+
4. 根据第3条规则来计算的话, 我们发现dp[5]=0, dp[6]=2, 但是显然, dp[6]应该为6才对, 但是我们发现可以将"(())"和"()"进行拼接, 即: dp[i] += dp[i-dp[i]], 即: dp[6] = 2 + dp[6-2] = 2 + dp[4] = 6
38+
39+
根据以上规则, 我们求解dp数组的结果为: [0, 0, 0, 2, 4, 0, 6, 0], 其中最长有效括号对的长度为6. 以下为图解:
40+
![32.longest-valid-parentheses](../assets/problems/32.longest-valid-parentheses.png)
41+
42+
## 关键点解析
43+
44+
1. 第3点特征, 需要检查的字符是s[i-1]和s[i-2-dp[i-1]], 根据定义可知: i-1 >= dp[i-1], 但是i-2不一定大于dp[i-1], 因此, 需要检查越界;
45+
3. 第4点特征最容易遗漏, 还有就是不需要检查越界, 因为根据定义可知: i >= dp[i], 所以dp[i-dp[i]]的边界情况是dp[0];
46+
47+
## 代码
48+
49+
* 语言支持: Python
50+
51+
Python Code:
52+
```
53+
class Solution:
54+
def longestValidParentheses(self, s: str) -> int:
55+
mlen = 0
56+
slen = len(s)
57+
dp = [0] * (slen + 1)
58+
for i in range(1, len(s) + 1):
59+
# 有效的括号对不可能会以'('结尾的
60+
if s[i - 1] == '(':
61+
continue
62+
63+
left_paren = i - 2 - dp[i - 1]
64+
if left_paren >= 0 and s[left_paren] == '(':
65+
dp[i] = dp[i - 1] + 2
66+
67+
# 拼接有效括号对
68+
if dp[i - dp[i]]:
69+
dp[i] += dp[i - dp[i]]
70+
71+
# 更新最大有效扩对长度
72+
if dp[i] > mlen:
73+
mlen = dp[i]
74+
75+
return mlen
76+
```
77+
78+
## 扩展
79+
80+
1. 如果判断的不仅仅只有'('和')', 还有'[', ']', '{'和'}', 该怎么办?
81+
2. 如果输出的不是长度, 而是任意一个最长有效括号对的字符串, 该怎么办?

0 commit comments

Comments
 (0)