leetcode-20230106.md
This commit is contained in:
@@ -16,8 +16,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="reveal">
|
<div class="reveal">
|
||||||
<div class="slides">
|
<div class="slides">
|
||||||
<section>Slide 1</section>
|
<section data-markdown="leetcode-20230106.md"></section>
|
||||||
<section>Slide 2</section>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -31,6 +30,8 @@
|
|||||||
// - https://revealjs.com/config/
|
// - https://revealjs.com/config/
|
||||||
Reveal.initialize({
|
Reveal.initialize({
|
||||||
hash: true,
|
hash: true,
|
||||||
|
height: 1000,
|
||||||
|
width: 1000,
|
||||||
|
|
||||||
// Learn about plugins: https://revealjs.com/plugins/
|
// Learn about plugins: https://revealjs.com/plugins/
|
||||||
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
|
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
|
||||||
|
|||||||
154
leetcode-20230106.md
Normal file
154
leetcode-20230106.md
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
### Leetcode 💻 寒假 20230106
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 20. Valid Parentheses
|
||||||
|
|
||||||
|
验证左右括号是否匹配 (利用Stack)
|
||||||
|
|
||||||
|
```cpp [|3-11|12-20|22-24|26|28|29-32|34-40|44|]
|
||||||
|
class Solution {
|
||||||
|
public:
|
||||||
|
// 判断左右括号是否相等
|
||||||
|
inline bool match(const char &left, const char &right) {
|
||||||
|
switch (left) {
|
||||||
|
case '(': return right == ')';
|
||||||
|
case '{': return right == '}';
|
||||||
|
case '[': return right == ']';
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 判断是不是左括号
|
||||||
|
inline bool is_left(const char &c) {
|
||||||
|
switch (c) {
|
||||||
|
case '(': return true;
|
||||||
|
case '{': return true;
|
||||||
|
case '[': return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool isValid(string s) {
|
||||||
|
// 判断长度是否为偶数
|
||||||
|
if (s.length() % 2 != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
stack<char> myStack;
|
||||||
|
|
||||||
|
for (auto const &c : s) {
|
||||||
|
if (is_left(c)) {
|
||||||
|
myStack.push(c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myStack.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!match(myStack.top(), c))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
myStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果结束之后 stack 中还有元素
|
||||||
|
return myStack.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
3-10 首先有两个辅助函数,一个叫match,用来判断左右括号是否相等,
|
||||||
|
|
||||||
|
12-20 然后是另一个函数慵懒判断是不是左括号。
|
||||||
|
|
||||||
|
22-24 进入主函数,先判断一下字符串长度是基数还是偶数,
|
||||||
|
如果是基数说明里面的括号肯定是不能左右匹配的,就可以直接返回false
|
||||||
|
|
||||||
|
26 然后创建一个stack类型的变量myStack
|
||||||
|
|
||||||
|
28 然后用变量c去遍历s,这里用到的是c++11的语法,auto是自动推断类型,
|
||||||
|
const表示c是不能被更改的,and符号表示这是一个左值引用,
|
||||||
|
c的类型可以简单理解为字符串中的字符
|
||||||
|
|
||||||
|
29-32 如果c是左括号,那么直接往stack中添加这个c,然后直接进入下一个循环
|
||||||
|
|
||||||
|
34-40 刚刚的语句已经把做括号的情况处理掉了,那么剩下的情况就是c是右括号的情况。
|
||||||
|
我们先检查stack中是否为空,为空的话说明stack中没有括号可以和c互相对应,
|
||||||
|
那么让函数返回false。
|
||||||
|
接著取stack中最顶的括号和c进行配对,如果不匹配返回false。
|
||||||
|
最后调用stack的pop方法,移除stack中最顶部的括号。
|
||||||
|
|
||||||
|
44 最后的最后,所有字符都匹配完了,如果stack中还残留有括号,
|
||||||
|
说明这个字符串也是不匹配的
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 84. Largest Rectangle in Histogram
|
||||||
|
|
||||||
|
```cpp [|2-4|6-8|26-28|9-10|12-14|16-20|23|26-31|]
|
||||||
|
int largestRectangleArea(vector<int> &heights) {
|
||||||
|
int ans = 0;
|
||||||
|
// 定义 stack 储存增序长方形
|
||||||
|
stack<int> order;
|
||||||
|
|
||||||
|
// 往 stack 中添加位于 index 的高度 height 的长方形
|
||||||
|
auto append = [&ans, &order, &heights]
|
||||||
|
(int index, int value) -> void {
|
||||||
|
// 计算单个长方形面积
|
||||||
|
ans = max(ans, value);
|
||||||
|
|
||||||
|
// stack 不为空 且 需要添加的长方形矮于 stack 中的长方形
|
||||||
|
while (!order.empty() &&
|
||||||
|
value < heights[order.top()]) {
|
||||||
|
|
||||||
|
// 计算面积
|
||||||
|
int h = heights[order.top()];
|
||||||
|
order.pop();
|
||||||
|
int w = index - 1 - (order.empty() ? -1 : order.top());
|
||||||
|
ans = max(ans, h * w);
|
||||||
|
}
|
||||||
|
|
||||||
|
order.push(index);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < heights.size(); i++) {
|
||||||
|
append(i, heights[i]);
|
||||||
|
}
|
||||||
|
// 处理edge case, 在最末尾添加一个高度为-1的长方形,
|
||||||
|
// 这将会计算stack中所有残留的长方形的面积
|
||||||
|
append(heights.size(), -1);
|
||||||
|
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
2-4 首先定义一个整数变量answer,代表这道题的计算结果,
|
||||||
|
然后定义一个stack,元素类型是整数,用来储存长方形的索引,
|
||||||
|
注意是储存的是长方形的索引不是长方形的高度。
|
||||||
|
|
||||||
|
6-8 然后由于这部分代码要在多个地方被调用,所以这里我用了c++11的匿名函数,
|
||||||
|
append是函数名,它接受两个参数,一个是index一个是value,它没有返回值,所以是void。
|
||||||
|
同时这个函数可以访问并修改ans,order,height,这里的and符号是表示捕获引用变量的意思,
|
||||||
|
各位理解为这个函数可以在函数内修改到函数外的变量就行了。
|
||||||
|
|
||||||
|
26-28 定义好函数之后会在一个循环中遍历题目给的这个高度列表,
|
||||||
|
然后调用函数,传入每个长方形的索引和高度
|
||||||
|
|
||||||
|
9-10 进入函数后首先计算单个长方形的面积
|
||||||
|
|
||||||
|
12-14 然后进入一个循环,
|
||||||
|
循环的条件是stack 不为空 且 需要添加的长方形矮于 stack 中的长方形
|
||||||
|
|
||||||
|
16-20 在循环内获得高度h和宽度w,注意这里先调用了pop然后在调用top,
|
||||||
|
如果stack里面是空的,那么调用top会引起奇怪的错误,所以一定要检查是否为空。
|
||||||
|
这里用了一个三元表达式,如果空则返回-1,否则正常返回top.
|
||||||
|
|
||||||
|
23 循环结束之后,也就是需要添加的长方形比stack中的长方形都高的时候,
|
||||||
|
我们可以把它添加仅stack了
|
||||||
|
|
||||||
|
26-31 这是刚刚看到调用append的代码
|
||||||
|
注意代码运行到这里stack中是还有长方形的,stack中残留的长方形还没有计算面积。
|
||||||
|
所以在最末尾的位置添加一个高度为-1的长方形,
|
||||||
|
由于stack中的所有长方形都是正数,加个-1进去会计算stack中残留的长方形面积。
|
||||||
Reference in New Issue
Block a user