栈(Stack)是一种基于先进后出(LIFO)原则的数据结构。栈的操作包括入栈(Push)和出栈(Pop),入栈操作将元素压入栈顶,出栈操作将栈顶元素弹出。栈还有其他常见的操作,如查看栈顶元素(Peek)和判断栈是否为空(IsEmpty)等。
在算法和数据结构中,栈是一个非常有用的工具。在解决许多问题时,栈可以帮助我们更容易地管理数据和确定执行顺序。在这里,我将分享几个关于如何使用栈进行刷题的技巧。
- 逆波兰表达式求值
逆波兰表达式是一种不需要括号的数学表达式表示方式。例如,表达式“3+4”可以表示为“3 4 +”。求解逆波兰表达式的方法是使用栈来保存数字,并在遇到运算符时弹出两个数字进行计算。
使用栈求解逆波兰表达式的代码如下:
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for (String token : tokens) {
if (token.equals("+")) {
stack.push(stack.pop() + stack.pop());
} else if (token.equals("-")) {
int b = stack.pop();
int a = stack.pop();
stack.push(a - b);
} else if (token.equals("*")) {
stack.push(stack.pop() * stack.pop());
} else if (token.equals("/")) {
int b = stack.pop();
int a = stack.pop();
stack.push(a / b);
} else {
stack.push(Integer.parseInt(token));
}
}
return stack.pop();
}
- 括号匹配
括号匹配是一个经典的栈应用场景。给定一个只包含括号字符的字符串,判断括号是否匹配。如果括号匹配,返回true,否则返回false。
使用栈判断括号匹配的代码如下:
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(' || c == '{' || c == '[') {
stack.push(c);
} else if (c == ')' && !stack.isEmpty() && stack.peek() == '(') {
stack.pop();
} else if (c == '}' && !stack.isEmpty() && stack.peek() == '{') {
stack.pop();
} else if (c == ']' && !stack.isEmpty() && stack.peek() == '[') {
stack.pop();
} else {
return false;
}
}
return stack.isEmpty();
}
- 最小栈
最小栈是一个栈数据结构,支持常规栈操作(入栈、出栈、查看栈顶元素),并且能够在常数时间内返回栈中的最小元素。
使用两个栈实现最小栈的代码如下:
class MinStack {
Stack<Integer> stack;
Stack<Integer> minStack;
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
public void push(int x) {
stack.push(x);
if (minStack.isEmpty() || x <= minStack.peek()) {
minStack.push(x);
}
}
public void pop() {
if (stack.peek().equals(minStack.peek())) {
minStack.pop();
}
stack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
以上是几个使用栈的算法和数据结构问题。在解决具体问题时,需要根据实际情况选择合适的数据结构和算法,并结合具体语言的特性进行实现。