返回
20. 有效的括号
前端
2024-01-12 16:24:27
代码随想录 | day11:栈和队列系列
引言:
欢迎来到代码随想录系列文章的第11篇。今天,我们将深入研究栈和队列数据结构的世界,探索三个令人着迷的算法问题:20. 有效的括号、1047. 删除字符串中的相邻重复项和150. 逆波兰表达式求值。让我们踏上这段算法之旅,以创新思维为向导,用清晰的逻辑和引人入胜的语言描绘出解决方案的画面。
问题:
给定一个只包含圆括号 "()"、"{}" 和 "[]" 的字符串,判断它是否有效。
解决方案:
解决这个问题的关键在于利用栈数据结构。我们将遍历输入字符串,如果遇到左括号,则将其压入栈中。如果遇到右括号,我们检查栈顶的元素是否与它匹配。如果是,我们就弹出栈顶元素。否则,字符串无效。这个过程一直持续到字符串结束或栈变为空。
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(' || c == '{' || c == '[') {
stack.push(c);
} else {
if (stack.isEmpty() || !isMatch(stack.pop(), c)) {
return false;
}
}
}
return stack.isEmpty();
}
private boolean isMatch(char left, char right) {
return (left == '(' && right == ')') || (left == '{' && right == '}') || (left == '[' && right == ']');
}
问题:
给定一个字符串,删除所有相邻的重复项,返回结果字符串。
解决方案:
对于这个问题,我们使用了一个栈来存储字符。当我们遇到与栈顶相同的字符时,我们弹出它。否则,我们将其压入栈中。这个过程一直持续到字符串结束。最后,我们将栈中剩余的字符连接起来,形成结果字符串。
public String removeDuplicates(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (!stack.isEmpty() && stack.peek() == c) {
stack.pop();
} else {
stack.push(c);
}
}
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
return sb.reverse().toString();
}
问题:
给定一个逆波兰表达式(后缀表达式),求其值。
解决方案:
逆波兰表达式是一种后缀表达式,运算符写在操作数之后。要解决这个问题,我们使用了一个栈。当我们遇到一个操作数时,我们将其压入栈中。当我们遇到一个运算符时,我们弹出栈顶的两个元素,执行运算,然后将结果压入栈中。这个过程一直持续到表达式结束。最后,栈中剩下的元素就是表达式的值。
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for (String token : tokens) {
if (isOperator(token)) {
int num1 = stack.pop();
int num2 = stack.pop();
int result = calculate(num2, num1, token);
stack.push(result);
} else {
stack.push(Integer.parseInt(token));
}
}
return stack.pop();
}
private boolean isOperator(String token) {
return token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/");
}
private int calculate(int num1, int num2, String operator) {
switch (operator) {
case "+":
return num1 + num2;
case "-":
return num2 - num1;
case "*":
return num1 * num2;
case "/":
return num2 / num1;
default:
throw new IllegalArgumentException("Invalid operator: " + operator);
}
}