栈和队列初步刷题篇

两个栈实现队列

方法:
两种倒入方法

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();
    }
}

你可能感兴趣的:(算法刷题,java,数据结构,算法,leetcode)