代码随想录算法训练营| 232.用栈实现队列 、 225. 用队列实现栈 、 20. 有效的括号 、 1047. 删除字符串中的所有相邻重复项

232.用栈实现队列

题目

参考文章

思路:这题的思路就是用两个栈来实现队列的输出,因为队列是先进先出原则,所以当有元素如队列时,把这些元素加入到输入栈stackIn中,如果要输出的时候,要先判断输出栈stackOut是否有元素,如果有元素直接输出,如果没有元素就把输入栈中的所有元素加入到输出栈之后再输出(这里为什么是所有元素呢,如果你不把statckIn中所有元素都压入stackOut中,后续输出会得不到队列的输出结果的,自己可以试着举例试试)

代码:

class MyQueue {
    Stack<Integer> stackIn;
    Stack<Integer> stackOut;

    public MyQueue() {
        stackIn = new Stack<>(); // 进栈
        stackOut = new Stack<>(); // 出栈
    }
    
    public void push(int x) {
        stackIn.push(x);
    }
    
    public int pop() {
        dumpstackIn();
        return stackOut.pop();
    }
    
    public int peek() {
        dumpstackIn();
        return stackOut.peek();
    }
    
    public boolean empty() {
         return stackIn.isEmpty() && stackOut.isEmpty();
    }

    private void dumpstackIn(){
        if(!stackOut.isEmpty()) return ;
        while(!stackIn.isEmpty()){
            stackOut.push(stackIn.pop());
        }
    }
}

 225. 用队列实现栈

题目

参考文章

思路:这里运用一个队列实现栈。首先push即正常入栈queue.add();pop时,因为要删除的是栈顶元素,但是我们push把它放到了队列的末尾,所以我们要设置一个rePosistion方法,把出来这个栈顶元素外的其他元素提取出来重新加入到队列中,再queue.poll()即可得到栈顶元素;top时,就是把栈顶元素提取出来,但是不删除,所以我们执行rePosition方法后,把栈顶元素用result存储,再把result存入队列中,保证了原始入队列的顺序不变,后续只要执行rePosition还是可以得到该栈顶元素

代码:

class MyStack {
    Queue<Integer> queue;

    public MyStack() {
        queue = new LinkedList<>();
    }
    
    public void push(int x) {
        queue.add(x);
    }
    
    public int pop() {
        rePosition();
        return queue.poll();
    }
    
    public int top() {
        rePosition();
        //因为上面是把栈顶元素提到了队列最前面
        int result=queue.poll();
        //这里把队列的第一个元素提取出来后,再添加回队列中,就又保留了原来的入栈顺序,只要后面提取栈顶时再把元素提到队列最前面即可
        queue.add(result);
        return result;
    }
    
    public boolean empty() {
        return queue.isEmpty();
    }

    //把除了栈顶元素外的其他元素提取出来重新加入加入队列中
    public void rePosition(){
        int size=queue.size();
        size--;
        while(size-->0){
            queue.add(queue.poll());
        }
    }
}

20. 有效的括号

题目

参考文章

思路:设置一个栈,当遍历字符串时,如果遇到左括号,把对应的右括号放入栈中;当字符串还未遍历完,但是栈已经空了则返回false,如果遇到的是右括号,但是与栈中的栈顶的右括号不匹配,则返回false,如果与栈顶的右括号匹配,则删除栈顶元素,直到字符串遍历完。最后,如果当栈不为空,就表示此时的字符串的左括号多了,也是返回false,栈为空就返回true

代码:

class Solution {
    public boolean isValid(String s) {
        Deque<Character> deque = new LinkedList<>();
        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){
                //当字符串还未遍历完,但是栈已经为空,或者栈顶元素不等于当前遇到的右括号字符,则返回fasle
                return false;
            }else{
                //表示此时栈顶的元素和当前遍历的右括号字符匹配,则去除栈顶元素
                deque.pop();
            }
        }
        //遍历到最后如果栈中还有元素,表示左括号多了,返回fasle即可
        return deque.isEmpty();
    }
}

1047. 删除字符串中的所有相邻重复项

题目

参考文章

思路:本题思路是用字符串代替栈的形式,获取最终字符串,省去转换字符串的转换。首先定义一个StringBuffer,设置一个默认长度top(用于后续比较);然后循环字符串s,判断当res中有元素,而且该元素与当前遍历到的字符相同时,则把当前res中的元素删除,res长度-1;若res用有元素且不与当前字符相同或者res没有元素时,就把当前的字符加入到res中,长度+1 。最后返回res的字符串形式即可

解释:这里为什么是res.charAt(top)和 res.deleteCharAt(top),因为我们把这个res的头作为栈尾,res的尾作为栈顶,所以删除的时候就是直接删除栈顶来操作,是为了后面防止倒叙输出字符串了

代码:

class Solution {
    public String removeDuplicates(String s) {
        //用字符串代表栈
        StringBuffer res=new StringBuffer();
        //代表res长度
        int top=-1;

        for(int i=0;i<s.length();i++){
            char c=s.charAt(i);
            //当res长度大于等于零即表示有元素时,而且res栈顶元素等于当前字符,则删除该栈顶元素
            if(top>=0&&res.charAt(top)==c){
                res.deleteCharAt(top);
                top--;
            }else{
                //否则则添加该字符到栈中
                res.append(c);//加入到res末尾
                top++;//长度+1
            }
        }
        //转换为字符串
        return res.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值