Files
reveal.js/leetcode-20230106.md
2023-01-10 01:23:49 +08:00

5.0 KiB
Raw Blame History

Leetcode 💻 寒假 20230106


20. Valid Parentheses

验证左右括号是否匹配 (利用Stack)

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

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中残留的长方形面积。