LeeCode 栈与队列问题(一)

LeeCode 20: 有效的括号

题目描述

给定一个只包括 '(', ')', '{', '}', '[', ']' 的字符串s,判断字符串是否有效。

有效字符串满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

建立模型

  1. 这是一个典型的栈结构的问题
  2. 遇到左括号则入栈,遇到右括号则将栈顶的左括号弹出,并判断是否匹配
    • 匹配:继续下一个字符
    • 不匹配:返回 False,不是有效的字符串
  3. 遍历字符串s的每一个字符,若最后栈为空,则说明字符串有效

代码实现

# Python3 实现
def isValid(self, s: str) -> bool:
    if len(s) % 2:
        return False
    
    dict = {}
    dict[')'] = '('
    dict['}'] = '{'
    dict[']'] = '['

    stack = []
    for ch in s:
        if ch in dict.keys():
            if not stack or stack[-1] != dict[ch]:
                return False
            stack.pop()
        else:
            stack.append(ch)
    return not stack
// Java 实现
public boolean isValid(String s) {
  if (s.length() % 2 != 0) {
    return false;
  }

  Map<Character, Character> map = new HashMap<>();
  map.put(')', '(');
  map.put('}', '{');
  map.put(']', '[');

  Stack<Character> stack = new Stack<>();
  for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);

    if (map.containsKey(c)) {
      if (stack.isEmpty() || stack.peek() != map.get(c)) {
        return false;
      }
      stack.pop();
    }
    else {
      stack.push(c);
    }
  }

  return stack.isEmpty();
}

LeeCode 1047: 删除字符串中的所有相邻重复项

题目描述

给出由小写字母组成的字符串 S ,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。在完成所有重复项删除操作后返回最终的字符串,答案保证唯一。

建立模型

  1. 本题和上面有效的括号属于同一类问题
  2. 遍历字符串 S 的每一个字符,若当前字符 == 栈顶字符,则弹出栈顶(等价于删除),否则将当前字符入栈。
  3. 返回栈中最后剩余的字符组成的串

代码实现

# Python3 实现
def RemoveDuplicates(self, s: str) -> str:
    stack = []
    for c in s:
        if not stack:
            stack.append(c)
        else:
            peek = stack[-1]
            if peek == c:
                stack.pop()
                continue
            else:
                stack.append()
    return ''.join(stack)
// Java 实现
public String RemoveDuplicates(String s) {
  Stack<Character> stack = new Stack<>();

  for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);
    if (stack.isEmpty() || c != stack.peek()) {
      stack.push(c);
    }
    else {
      stack.pop();
    }
  }

  StringBuilder sb = new StringBuilder();
  while (!stack.isEmpty()) {
    sb.insert(0, stack.pop());
  }
  return sb.toString();
}

LeeCode 150: 逆波兰表达式求值

题目描述

根据 逆波兰表达式,求表达式的值。

有效的运算符包括 +, -, *, /。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

建立模型

  1. 本题也是一个栈的问题
  2. 当遇到操作符时,弹出栈顶两个元素用于计算
  3. 当遇到操作数时,则入栈
  4. 最后返回结果

代码实现

# Python3 实现
def EvalRPN(self, tokens: List[str]) -> int:
    stack = []
    ops = ['+', '-', '*', '/']
    for token in tokens:
        if token not in ops:
            stack.append(int(token))
        else:
            data1 = stack.pop()
            data2 = stack.pop()
            if token == '+':
                stack.append(data2 + data1)
            elif token == '-':
                stack.append(data2 - data1)
            elif token == '*':
                stack.append(data2 * data1)
            elif token == '/':
                stack.append(int(data2 / data1))
            else:
                print("Unknown Condition.")
                return 0
    return stack.pop()
// Java 实现
public int EvalRPN(String[] tokens) {
  Stack<Integer> stack = new Stack<>();
  Set<String> ops = new HashSet<>();    /* 存储操作符 */
  set.add("+");
  set.add("-");
  set.add("*");
  set.add("/");

  for (String token : tokens) {
    if (!ops.contains(token)) {
      stack.push(Integer.valueOf(token));
    }
    else {
      int data1 = stack.pop();
      int data2 = stack.pop();

      switch(token) {
        case "+":
          stack.push(data2 + data1);
          break;
        case "-":
          stack.push(data2 - data1);
          break;
        case "*":
          stack.push(data2 * data1);
          break;
        case "/":
          stack.push(data2 / data1);
          break;
        default:
          System.out.println("Unknown Condition!");
      }
    }
  }
  return stack.pop();
}
posted @ 2022-07-09 23:25  ylyzty  阅读(24)  评论(0编辑  收藏  举报