代码随想录第九天|栈队列互相实现|有效的括号|删除字符串中所有的相邻重复项

关于各种语言中对队列和栈的介绍,可以参考这个网址中的内容:Hello算法,对于Java语言的集合框架的介绍可以参考这里

232. 用栈实现队列

文档讲解:代码随想录
视频讲解:B站视频
状态:AC

只使用栈的方法实现队列的方法。这就需要我们对存储在栈内部的数据进行一次倒序排序,可以通过两个栈来实现队列的方法,一个栈保存输入,另一个栈在需要输出的时候,转移数据并输出数据。因此,栈的实例成员如下:

class MyQueue {
    ArrayDeque<Integer> input = null;
    ArrayDeque<Integer> stack = null;
}

而入队操作则将数据存储在第一个栈中,等到需要出队时再通过pop方法对数据进行重新排序以满足队列的要求,这时,数据便转移到了另一个栈中,用栈实现队列的pop方法复杂度为O(n)。另外,peek()方法类似,下面一并给出代码:

class MyQueue {
    ArrayDeque<Integer> input = null;
    ArrayDeque<Integer> stack = null;

    public MyQueue() {
        this.stack = new ArrayDeque<>();
        this.input = new ArrayDeque<>();
    }
    
    public void push(int x) {
        input.push(x);

    }
    
    public int pop() {
        if (stack.isEmpty()) {
            while (!input.isEmpty()) 
                stack.push(input.pop());
        }
            return stack.pop();
    }
    
    public int peek() {
        if (stack.isEmpty()) {
            while (!input.isEmpty())  {
                stack.push(input.pop());
            }
        }
        return stack.peek();
    }
    
    public boolean empty() {
        return input.isEmpty() && stack.isEmpty();

    }
}

225. 用队列实现栈

文档讲解:代码随想录
视频讲解:B站视频
状态:使用两个队列可以解决,需要复习。

这道题与上一道题略有不同,在用栈实现队列时,栈本身的出栈操作就会倒序元素,但是队列的出队操作不会倒序元素,因此我们需要在出队时保留一个元素,然后输出或者查看这个元素。这时,两个队列中,其中一个队列只包含一个元素,用于出栈或者查看,另一个队列保存其他元素。并且每进行一次出栈,都会让两个队列的功能互换,还需要一个flag用于确定哪个队列用于出栈操作,哪个队列用于保存元素。具体代码如下:

class MyStack {
    private ArrayDeque<Integer> temp = null;
    private ArrayDeque<Integer> stack = null;
    private byte flag;

    public MyStack() {
        this.temp = new ArrayDeque<>();
        this.stack = new ArrayDeque<>();
    }
    
    public void push(int x) {
        if (flag == 0) temp.offer(x);
        else stack.offer(x);
    }
    
    public int pop() {
        if (flag == 0) {
            while (temp.size() > 1) {
                stack.offer(temp.poll());
            }
            flag = 1;
            return temp.poll();
        }
        else {
            while (stack.size() > 1) {
                temp.offer(stack.poll());
            }
            flag = 0;
            return stack.poll();
        }

    }
    
    public int top() {
        if (flag == 0) {
            while (temp.size() > 1) {
                stack.offer(temp.poll());
            }
            return temp.peek();
        }
        else {
            while (stack.size() > 1) {
                temp.offer(stack.poll());
            }
            return stack.peek();
        }
    }
    public boolean empty() {
        return temp.isEmpty() && stack.isEmpty();

    }
}

20.有效括号

文档讲解:代码随想录
视频讲解:B站视频
状态:AC,使用栈判断

这道题在输入右括号时需要判读上一个元素,在输入完成时,需要判断是否能相互对应,适合使用栈操作。

这里将输入左括号建模为push一个元素,输入右括号建模为pop上一个元素,如果右括号不能与左括号对应则false。

在输入左括号时,根据括号类型的不同,push一个元素,在输入右括号时,根据前一个元素的类别,决定是pop上一个元素,还是返回false。具体代码如下:

class Solution {
    public boolean isValid(String s) {
        ArrayDeque<Integer> stack = new ArrayDeque<>();
        for (int i = 0; i < s.length(); i++) {
            switch (s.charAt(i)) {
                case '(':
                    stack.push(1);
                    break;
                case '[':
                    stack.push(2);
                    break;
                case '{':
                    stack.push(3);
                    break;
                case ')':
                    if (stack.isEmpty() || stack.pop() != 1) return false;
                    break;
                case ']':
                    if (stack.isEmpty() || stack.pop() != 2) return false;
                    break;
                case '}':
                    if (stack.isEmpty() || stack.pop() != 3) return false;
                    break;
            }
        }
        return stack.isEmpty();
    }
}

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

文档讲解:代码随想录
视频讲解:B站视频
状态:较为简单,AC

这道题需要删除一个字符串中的重复子串,适合使用栈来解决。栈的结构特点让我们能够能够将当前元素与栈顶元素进行对比,查看是否重复。这道题较为简单,直接给出代码。

class Solution {
    public String removeDuplicates(String s) {
        ArrayDeque<Character> stack = new ArrayDeque<>();
        for (int i = 0; i < s.length(); i++) {
            if (i == 0) stack.push(s.charAt(i));
            else {
                if (!stack.isEmpty() && stack.peek() == s.charAt(i))
                    stack.pop();
                else stack.push(s.charAt(i));
            }
        }

        char[] res = new char[stack.size()];
        for (int i = res.length - 1; i >= 0; i--) {
            res[i] = stack.pop();
        }
        return new String(res);

    }
}
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值