参考:https://gitee.com/programmercarl/leetcode-master
Java创建栈
import java.util.Stack;
Stack<Integer> s = new Stack<Integer>(); 只能装整形的栈
Stack<Character> s = new Stack<Character>(); 只能装字符型的栈
s.push();
s.pop();
//使用双向链表实现
LinkedList<Integer> stack = new LinkedList<>();
stack.add();
stack.pop();
官方推荐
Deque<Integer> stack = new ArrayDeque<>();
————————————————
版权声明:本文为CSDN博主「乐1239」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_30769517/article/details/115298991
232. 用栈实现队列
用两个栈实现先入先出队列
数据先放到第一个栈里,再先入后出放到第二个栈里,这样栈顶元素就是最先进栈1的元素了,可以实现先入先出
push:先由顺序正确的栈(设为栈2)先入后出到空栈(栈1),数据进栈1,栈1元素先入后出到栈2,这样最后进来的元素就压入栈底了
pop:由顺序正确的栈(栈2)pop栈顶
peek:读取栈2的栈顶
isEmpty:两个栈都为空就是空
class MyQueue {
Stack<Integer> s1;
Stack<Integer> s2;
public MyQueue() {
s1 = new Stack<>();
s2 = new Stack<>();
}
private int front;
public void push(int x) {
if (s1.empty())
front = x;
while (!s1.isEmpty())
s2.push(s1.pop());
s2.push(x);
while (!s2.isEmpty())
s1.push(s2.pop());
}
public int pop() {
int res=s1.pop();
if (!s1.empty())
front = s1.peek();
return res;
}
public int peek() {
return front;
}
public boolean empty() {
return s1.isEmpty();
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
225. 用队列实现栈
push:
由此分析,最简单的应该是s1当栈,s2辅助、s2当栈,s1辅助这样轮流来,但是为了方便代码的编写,还是统一s1当栈
pop:s1.pop
top:s1.peak
isEmpty:s1.isEmpty
class MyStack {
Queue<Integer> q1;
Queue<Integer> q2;
public MyStack() {
q1=new LinkedList<Integer>();
q2=new LinkedList<Integer>();
}
public void push(int x) {
while(!q1.isEmpty()){
q2.offer(q1.poll());
}
q1.offer(x);
while(!q2.isEmpty()){
q1.offer(q2.poll());
}
}
public int pop() {
return q1.poll();
}
public int top() {
return q1.peek();
}
public boolean empty() {
return q1.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
20. 有效的括号
遍历字符串
碰到左括号就把右括号压入栈
碰到右括号,如果栈空或者与栈顶不匹配,返回false
否则弹出栈顶元素
如果最后栈空,返回true
class Solution {
public boolean isValid(String s) {
Deque<Character> deque = new LinkedList<Character>();
char ch;
for (int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
//碰到左括号,就把相应的右括号入栈
if (ch == '(') {
deque.push(')');
}else if (ch == '{') {
deque.push('}');
}else if (ch == '[') {
deque.push(']');
} else if (deque.isEmpty() || deque.peek() != ch) {//碰到右括号,如果此时栈空或者与栈顶不匹配返回false
return false;
}else {//否则就是匹配了,弹出栈顶
deque.pop();
}
}
//最后判断栈中元素是否匹配
return deque.isEmpty();
}
}
1047. 删除字符串中的所有相邻重复项
与栈顶元素不同,则压入栈,否则:丢掉该元素并且弹出栈顶元素
class Solution {
public String removeDuplicates(String s) {
Deque<Character> stack = new ArrayDeque<>();
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
if(stack.isEmpty() || ch!=stack.peek()){
stack.push(ch);
}else{
stack.pop();
}
}
String str="";
while(!stack.isEmpty()){
str=stack.pop()+str;
}
return str;
}
}
150. 逆波兰表达式求值
构建一个栈,数字就入栈,操作数就弹出来两个操作数,先弹出来的op2,后弹出来的op1,运行op1 op op2,结果压入栈
class Solution {
public int evalRPN(String[] tokens) {
Deque<Integer> stack = new LinkedList<Integer>();
int n=tokens.length;
for(int i=0;i<n;i++){
String token=tokens[i];
if(isNumber(token)){
stack.push(Integer.parseInt(token));
}else{
int num2=stack.pop();
int num1=stack.pop();
switch(token){
case "+":
stack.push(num1+num2);
break;
case "-":
stack.push(num1-num2);
break;
case "*":
stack.push(num1*num2);
break;
case "/":
stack.push(num1 / num2);
break;
default:
}
}
}
return stack.pop();
}
public boolean isNumber(String s){
return !("+".equals(s) ||"-".equals(s) ||"*".equals(s) ||"/".equals(s) );
}
}