第一题:逆波兰表达式求值
给你一个字符串数组 tokens ,表示一个根据逆波兰表示法表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
- 有效的算符为 ‘+’、‘-’、‘*’ 和 ‘/’ 。
- 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
- 两个整数之间的除法总是 向零截断 。
- 表达式中不含除零运算。
- 输入是一个根据逆波兰表示法表示的算术表达式。
- 答案及所有中间计算结果可以用 32 位 整数表示。
示例 1:
输入:tokens = [“2”,“1”,“+”,“3”,“*”]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:
输入:tokens = [“4”,“13”,“5”,“/”,“+”]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:
输入:tokens = [“10”,“6”,“9”,“3”,“+”,“-11”,““,”/“,””,“17”,“+”,“5”,“+”]
输出:22
解释:该算式转化为常见的中缀算术表达式为:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
提示:
- 1 <= tokens.length <= 104
- tokens[i] 是一个算符(“+”、“-”、“*” 或 “/”),或是在范围 [-200, 200] 内的一个整数
解题思路:
- 构造isOperation方法判断字符串x是否为运算符
- 如果不是运算符,则将x转为int类型放到栈里
- 如果为运算符,stack弹出两个整数,判断为哪个运算符,并对两个整数进行相应的运算,最后返回stack弹出的整数
代码实现:
class Solution {
private Boolean isOperation(String s) {
if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")) {
return true;
}
return false;
}
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for(String x:tokens) {
if(!isOperation(x)) {
stack.push(Integer.parseInt(x));
}else {
int num2 = stack.pop();
int num1 = stack.pop();
switch(x) {
case "+":
stack.push(num1+num2);
break;
case "-":
stack.push(num1-num2);
break;
case "*":
stack.push(num1*num2);
break;
case "/":
stack.push(num1/num2);
break;
}
}
}
return stack.pop();
}
}
第二题:有效的括号
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
提示:
- 1 <= s.length <= 104
- s 仅由括号 ‘()[]{}’ 组成
解题思路:
- 遍历字符串,如果为左括号,则入栈
- 如果为右括号,则判断与栈顶元素是否匹配,若匹配,则出栈
- 字符串遍历完之后,如果栈为空,则左右括号匹配
代码实现:
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for(int i = 0;i < s.length();i++) {
char ch = s.charAt(i);
if(ch == '('||ch == '['||ch == '{') {
stack.push(ch);
}else {
if(stack.empty()) {
return false;
}
char top = stack.peek();
if((top == '('&&ch == ')')||(top == '['&&ch == ']')||(top == '{'&&ch == '}')) {
stack.pop();
}else {
return false;
}
}
}
if(!stack.empty()) {
return false;
}
return true;
}
}
第三题:栈的压入、弹出序列
描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
- 0<=pushV.length == popV.length <=1000
- -1000<=pushV[i]<=1000
- pushV 的所有数字均不相同
示例1
输入: [1,2,3,4,5],[4,5,3,2,1]
返回值: true
说明:可以通过push(1)=>push(2)=>push(3)=>push(4)=>pop()=>push(5)=>pop()=>pop()=>pop()=>pop()
这样的顺序得到[4,5,3,2,1]这个序列,返回true
示例2
输入: [1,2,3,4,5],[4,3,5,1,2]
返回值: false
说明:由于是[1,2,3,4,5]的压入顺序,[4,3,5,1,2]的弹出顺序,要求4,3,5必须在1,2前压入,且1,2不能弹出,但是这样压入的顺序,1又不能在2之前弹出,所以无法形成的,返回false
解题思路:
- 用栈接收pushed里的元素,判断栈顶元素与popped数组j下标的元素是否相等
- 若相等,则弹出栈顶元素,j++,若不相等,则继续往栈里放元素
- 循环结束后,返回stack.empty()
代码实现:
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> stack = new Stack<>();
int j = 0;
for(int i = 0;i < pushed.length;i++) {
stack.push(pushed[i]);
while(j < popped.length&&!stack.empty()&&stack.peek() == popped[j]) {
stack.pop();
j++;
}
}
return stack.empty();
}
}
第四题:最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
- MinStack() 初始化堆栈对象。
- void push(int val) 将元素val推入堆栈。
- void pop() 删除堆栈顶部的元素。
- int top() 获取堆栈顶部的元素。
- int getMin() 获取堆栈中的最小元素。
示例 1:
输入: [“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”] [[],[-2],[0],[-3],[],[],[],[]]
输出: [null,null,null,null,-3,null,0,-2]解释: MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
提示:
- -231 <= val <= 231 - 1
- pop、top 和 getMin 操作总是在 非空栈 上调用
- push, pop, top, and getMin最多被调用 3 * 104 次
解题思路:
- 用两个栈stack,minStack实现最小栈
- 入栈操作时,将元素放入stack中,如果minStack为空,则将元素放入minStack中,若不为空,判断元素值是否小于等于minStack栈顶值,如果小于或等于,则将元素放入minStack
- 出栈操作时,先判断stack是否为空,判断stack弹出元素值与minStack栈顶元素值是否相等,若相等,则弹出minStack栈顶元素
- 获取栈顶元素时,先判断stack是否为空,然后获取stack栈顶元素值
- 获取栈最小元素时,先判断minStack是否为空,然后获取minStack栈顶元素值
代码实现:
class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
public void push(int val) {
stack.push(val);
if(minStack.empty()) {
minStack.push(val);
}else {
if(minStack.peek() >= val) {
minStack.push(val);
}
}
}
public void pop() {
if(stack.empty()) {
return;
}
int x = stack.pop();
if(x == minStack.peek()) {
minStack.pop();
}
}
public int top() {
if(stack.empty()) {
return -1;
}
return stack.peek();
}
public int getMin() {
if(minStack.empty()) {
return -1;
}
return minStack.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/