两个栈实现队列
方法:
两种倒入方法
class MyQueue {
Stack<Integer> stackIn ;
Stack<Integer> stackOut ;
public MyQueue() {
stackIn=new Stack<>();
stackOut=new Stack<>();
}
public void InToOut(){
while(!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
}
//弹完一个后,不想弹了,重新入In
public void outToIn(){
while(!stackOut.isEmpty()){
stackIn.push(stackOut.pop());
}
}
public void push(int x) {
//每次弹完我都会重新弹回来
stackIn.push(x);
}
public int pop() {
InToOut();
int result= stackOut.pop();
outToIn();
return result;
}
public int peek() {
InToOut();
int result= stackOut.peek();
outToIn();
return result;
}
public boolean empty() {
return stackOut.isEmpty()&&stackIn.isEmpty();
}
}
class MyQueue {
Stack<Integer> stackIn ;
Stack<Integer> stackOut ;
public MyQueue() {
stackIn=new Stack<>();
stackOut=new Stack<>();
}
public void InToOut(){
//弹之前的操作,我有元素,我不需要你倒入;我没有元素才需要你倒入
if(!stackOut.isEmpty()) return;
while(!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
InToOut();
return stackOut.pop();
}
public int peek() {
InToOut();
return stackOut.peek();
}
public boolean empty() {
return stackOut.isEmpty()&&stackIn.isEmpty();
}
}
队列实现栈
方法:
一个队列
两个队列
class MyStack {
Queue<Integer> que;
Queue<Integer> help;
public MyStack() {
que=new LinkedList<>();
help=new LinkedList<>();
}
public void push(int x) {
que.add(x);
}
public int pop() {
int size= que.size();
size--;
while(size-->0){
help.add(que.poll());
}
int result=que.poll();
Queue<Integer> temp=que;
que=help;
help=temp;
return result;
}
public int top() {
int size= que.size();
size--;
while(size-->0){
help.add(que.poll());
}
int result=que.peek();
//peek的还要压回去才可以交换队列
help.add(que.poll());
Queue<Integer> temp=que;
que=help;
help=temp;
return result;
}
public boolean empty() {
return que.isEmpty();
}
}
class MyStack {
Queue<Integer> que;
public MyStack() {
que=new LinkedList<>();
}
public void push(int x) {
que.add(x);
}
public int pop() {
int size= que.size();
size--;
while(size-->0){
que.add(que.poll());
}
//把最后一个弹出
int result=que.poll();
return result;
}
public int top() {
int size= que.size();
size--;
while(size-->0){
que.add(que.poll());
}
int result=que.peek();
que.add(que.poll());
return result;
}
public boolean empty() {
return que.isEmpty();
}
}
有效括号问题
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。``
方法:
利用栈
class Solution {
public boolean isValid(String s) {
//遍历字符串,左括号就压入右括号,到了右括号,判断是否和peek一样,不一样就false,一样就把之前比较的peek弹出
Stack<Character> stack=new Stack<>();
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='('){
stack.push(')');
}else if(s.charAt(i)=='{'){
stack.push('}');
}else if(s.charAt(i)=='['){
stack.push(']');
}else if(stack.isEmpty()||stack.peek()!=s.charAt(i)){//如果不匹配
return false;
}else{//匹配
stack.pop();
}
}
//比对正确
return stack.isEmpty();
}
}
删除字符所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:“abbaca”
输出:“ca”
解释:例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa” 可以执行重复项删除操作,所以最后的字符串为 “ca”。
方法:
利用栈来找到相邻过程相邻
class Solution {
public String removeDuplicates(String s) {
//借助栈(刚刚好实现相邻):相邻就弹出,不相邻就压入,最后弹出拼接
Stack<Character> stack=new Stack<>();
for(int i=0;i<s.length();i++){
if(stack.isEmpty()) stack.push(s.charAt(i));
else if(s.charAt(i)==stack.peek()) stack.pop();
else stack.push(s.charAt(i));
}
char[] arr=new char[stack.size()];
for(int i=arr.length-1;i>=0;i--){
arr[i]=stack.pop();
}
return new String(arr);
}
}
根据逆波兰表达式求值
根据 逆波兰表示法,求表达式的值。
有效的运算符包括 + , - , * , / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入: [“2”, “1”, “+”, “3”, " * "]
输出: 9
解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
方法:
和删除重复项一样,只是不是比对了,而是运算
PS:leetcode上内置的jdk不能用'=='判断字符串相等问题
class Solution {
public int evalRPN(String[] tokens) {
//遍历数组,数字直接入栈,操作符就取两个数操作结果入栈
//这里的数和操作符都是字符串,转化压入
Stack<Integer> stack=new Stack<>();
for(int i=0;i<tokens.length;i++){
if(tokens[i].equals("+")){//只有减和除才需要注意顺序
stack.push(stack.pop()+stack.pop());
}else if(tokens[i].equals("*")){
stack.push(stack.pop()*stack.pop());
}else if(tokens[i].equals("-")){
stack.push(-stack.pop()+stack.pop());
}else if(tokens[i].equals("/")){
int num2=stack.pop();
int num1=stack.pop();
stack.push(num1/num2);
}else{
//压入数字
stack.push(Integer.valueOf(tokens[i]));
}
}
return stack.pop();
}
}