文章目录
- 232.用栈实现队列
- 225.用队列实现栈
- 20.有效的括号
- 1047.删除字符串中的所有重复项
- 150.逆波兰表达式
232.用栈实现队列
文档讲解:用栈实现队列
视频链接:代码随想录-用栈实现队列
状态:ok
思路:
用两个栈实现队列操作;定义两个栈,一个栈用于出栈outStack,另一个栈用于入栈inStack;当outStack为空时,则将inStack中的元素依次出栈并且加入到outStack中;
代码:
class MyQueue {Stack<Integer> inStack;Stack<Integer> outStack;public MyQueue() {inStack = new Stack();outStack = new Stack();}public void push(int x) {inStack.push(x);}public int pop() {inToOutParam();return outStack.pop();}public int peek() {inToOutParam();return outStack.peek();}public boolean empty() {return inStack.isEmpty() && outStack.isEmpty();}//将inStack中的元素加入到outStack中public void inToOutParam() {if (outStack.isEmpty()) {while (!inStack.isEmpty()) {Integer param = inStack.pop();outStack.push(param);}}}
}
225.用队列实现栈
文档讲解:用队列实现栈
视频链接:代码随想录-用队列实现栈
状态:ok
思路:
用一个队列实现栈的话,入栈可以正常从队列的入口进入,出栈的时候将队列pop进行size-1次,然后依次重新push到队列,最后再进行一次pop将移除元素返回即可;
代码:
class MyStack {Deque<Integer> deque;public MyStack() {deque = new ArrayDeque<>();}public void push(int x) {deque.addFirst(x);}public int pop() {//此时,用一个队列实现栈的元素应该在队尾,我们将队列前边的所有元素都重新加入队列int num = deque.size() - 1;while (num > 0) {Integer last = deque.removeLast();deque.addFirst(last);num--;}return deque.removeLast();}public int top() {return deque.getFirst();}public boolean empty() {return deque.isEmpty();}
}
20.有效的括号
文档讲解:有效的括号
视频链接:代码随想录-有效的括号
状态:自己思路写的虽然成功了,但是代码效率不高
思路:
自己的思路是,创建两个栈,一个栈按照字符串的顺序放入一个栈strStack中,另一个栈tempStack用来临时存放左括号;
1、先将字符串字符从字符串尾至头依次压入strStack栈;
2、依次对strStack出栈,如果是左括号,则直接放入temp栈中,如果是右括号,则判断tempStack栈中的左括号和当前的右括号是否匹配,如果匹配则将tempStack也出栈,如果不匹配直接返回false;
3、最后判断两个栈是否都是空,如果都是空则校验通过;
代码:
class Solution {public boolean isValid(String s) {Stack<Character> tempStack = new Stack<>();Stack<Character> strStack = new Stack<>();for (int i = s.length()-1; i >=0; i--) {strStack.push(s.charAt(i));}while (!strStack.isEmpty()) {Character pop = strStack.pop();if (isLeft(pop)) { //如果是左括号就加入到temp栈中;tempStack.push(pop);continue;}if (isRight(pop)) {if (tempStack.isEmpty()) {return false;}//对temp进行出栈,如果temp出栈和pop对应上,则双双跳出,如果没对应上,直接返回false;if (isMatch(tempStack.peek(), pop)) {tempStack.pop();} else {return false;}}}return tempStack.isEmpty() && strStack.isEmpty();}public boolean isLeft(Character s) {return '(' == s || '[' == s || '{' == s;}public boolean isRight(Character s) {return ')' == s || ']' == s || '}' == s;}public boolean isMatch(Character left, Character right) {if ('(' == left && ')' == right) {return true;}if ('[' == left && ']' == right) {return true;}if ('{' == left && '}' == right) {return true;}return false;}
}
1047.删除字符串中的所有重复项
文档讲解:删除字符串中的重复项目
视频链接:代码随想录-删除字符串中的所有重复项
状态:ok
思路:
1、定义一个栈,用来存放相邻不重复的字符;
2、对字符串s进行遍历,每次遍历到的字符c对栈顶元素进行比较,如果相同则栈顶进行pop,如果不相同则将字符c压入栈;
3、最后将栈中的元素按照栈底到栈顶的顺序输出成字符串返回即可;
代码:
class Solution {public String removeDuplicates(String s) {//定义一个栈从来存放未重复的字母元素Deque<Character> deque = new ArrayDeque();for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (deque.isEmpty() || deque.getFirst() != c) {deque.addFirst(c);} else {deque.removeFirst();}}StringBuilder sb = new StringBuilder();while (!deque.isEmpty()) {sb.append(deque.removeLast());}return sb.toString();}
}
150.逆波兰表达式
文档讲解:逆波兰表达式
视频链接:代码随想录-逆波兰表达式
状态:之前做过逆波兰表达式的题,这题需要注意的是用弹出的第二个元素来作为"-“或者”/"的主数;
思路:
1、先创建一个用于存放操作数的栈numStack;
2、遍历整个数组,如果不为操作数则push进操作数栈numStack中,如果为操作符的话,则从操作数栈中弹出两个操作数进行运算,并且将运算结果重新push进numStack中;
3、最后的计算结果就是numStack的最后一个元素,即栈顶元素;
代码:
class Solution {public int evalRPN(String[] tokens) {//用于存放操作数的栈Stack<Integer> numStack = new Stack<>();for (int i = 0; i < tokens.length; i++) {String token = tokens[i];if (isCompute(token)) {Integer num1 = numStack.pop();Integer num2 = numStack.pop();if ("+".equals(token)) {numStack.push(num1+num2);}if ("-".equals(token)) {numStack.push(num2-num1);}if ("*".equals(token)) {numStack.push(num2*num1);}if ("/".equals(token)) {numStack.push(num2/num1);}} else {numStack.push(Integer.valueOf(token));}}return numStack.pop();}public boolean isCompute(String s) {return "+".equals(s) || "-".equals(s) || "*".equals(s) || "/".equals(s);}
}