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

目录

题目链接:232. 用栈实现队列 - 力扣(LeetCode)

题目链接:225. 用队列实现栈 - 力扣(LeetCode)

题目链接:20. 有效的括号 - 力扣(LeetCode)

题目链接:1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)


  The longest way must have its close; the gloomiest night will on to a morning.  

题目链接:232. 用栈实现队列 - 力扣(LeetCode)

用两个栈实现一个队列,思路如下:

  1. 使用两个栈 stack1stack2stack1 用于处理入队操作,stack2 用于处理出队和取队首操作;
  2. 入队操作将元素推入 stack1;
  3. 出队操作从 stack2 弹出元素。如果 stack2 为空,则将 stack1 中的所有元素弹出并推入 stack2,然后从 stack2 弹出元素;
  4. 取队首操作类似于出队操作,只是不弹出元素;
  5. 判断队列是否为空,只需检查 stack1stack2 是否都为空;
class MyQueue232 {
    // 使用两个栈实现一个队列
    private Stack<Integer> stack1;
    private Stack<Integer> stack2;

    public MyQueue232() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }

    public void push(int x) {
        stack1.push(x);
    }

    public int pop() {
        if (stack2.isEmpty()) { // 如果stack2为空,则将stack1的所有元素弹出并推入stack2
            while (!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();  // 从 stack2 弹出元素
    }

    public int peek() {
        if (stack2.isEmpty()) {
            while (!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();  // 从 stack2 获取队首元素
    }

    public boolean empty() {
        return stack1.empty() && stack2.isEmpty();
    }
}

题目链接:225. 用队列实现栈 - 力扣(LeetCode)

使用两个队列来实现一个栈,我们可以利用一个主队列queue1和一个辅助队列queue2来模拟栈的后进先出,思路如下(注意到其实不用queue2也可以实现,不管是增加元素还是删除元素的操作后,辅助队列queue2始终为空):

  1. 使用两个队列 queue1queue2,其中 queue1 用于存储栈的元素,queue2 用作辅助队列;
  2. push(x) 操作将元素入队到 queue2,然后将 queue1 中的所有元素依次出队并入队到 queue2。最后,交换 queue1queue2;
  3. pop() 操作直接从 queue1 中出队一个元素;
  4. top() 操作直接返回 queue1 的队首元素;
  5. empty() 操作检查 queue1 是否为空;
class MyStack225 {
    private Queue<Integer> queue1;
    private Queue<Integer> queue2;

    public MyStack225() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }

    public void push(int x) {
        queue2.offer(x);  // 元素入队到queue2

        while (!queue1.isEmpty()){  // 将 queue1 中的所有元素依次出队并入队到 queue2
            queue2.offer(queue1.poll());
        }

        // 交换queue1和queue2
        Queue<Integer> temp = queue1;
        queue1 = queue2;
        queue2 = temp;
    }

    public int pop() {
        return queue1.poll();
    }

    public int top() {
        return queue1.peek();
    }

    public boolean empty() {
        return queue1.isEmpty();  // queue2 始终为空
    }
}

题目链接:20. 有效的括号 - 力扣(LeetCode)

使用栈解决的经典问题。思路:在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了。

class Solution20 {
    public boolean isValid(String s) {
        // 使用栈解决括号匹配问题
        // 在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了
        if (s.length() % 2 != 0) return false;  // s长度为奇数 返回false
        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();
    }
}

题目链接:1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)

使用栈解决删除字符串重复相邻项。思路:如果当前字符与栈顶字符相同,则弹出栈顶字符;如果不同,则将当前字符压入栈中。

class Solution1047 {
    public String removeDuplicates(String s) {
        /**
         * 1 如果当前字符与栈顶字符相同,则弹出栈顶字符。
         * 2 如果不同,则将当前字符压入栈中。
         */
        Stack<Character> stack = new Stack<>();
        for (char c : s.toCharArray()){
            if (!stack.isEmpty() && stack.peek() == c){
                stack.pop();
            }else {
                stack.push(c);
            }
        }

        StringBuilder result = new StringBuilder();
        for (char c : stack){
            result.append(c);
        }
        return result.toString();
    }
}

-----------------------------------------------------------------------------------------------------------------------

最后记录一点:

前面两个问题中,创建栈我使用的 Stack<Character> stack = new Stack<>();

这其实是Java中老旧的栈对象实现方法了,而官方推荐使用 Deque 来替代 Stack。因为 Deque 接口提供了更全面和灵活的操作,并且它是接口,具有更好的扩展性。其中栈相关的函数名不变,只需将Stack<Character> stack = new Stack<>()替换成Deque<Character> stack = new LinkedList<>();就可以了。

Deque 是双端队列,支持在两端插入和删除元素。操作上可以使用 addFirstaddLast 来在两端插入元素,removeFirstremoveLast 来在两端删除元素,peekFirstpeekLast 来访问两端的元素。其更通用,可以用来实现队列的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值