代码随想录训练营Day10

40 阅读2分钟

232.用栈实现队列 leetcode.com/problems/im…

思路:用两个栈实现队列,因为队列是先进先出的,所以当push的时候,把数据放入push-in 栈,当pop的时候,判断push-out栈是否为空,如果不为空直接pop push-out栈,否则就把push-in的数据放到push-out中

class MyQueue {

    Deque<Integer> stackIn;
    Deque<Integer> stackOut;

    public MyQueue() {
         stackIn = new LinkedList<>(); // 负责进栈
        stackOut = new LinkedList<>(); // 负责出栈
        
    }
    
    // 直接把数据push进stackIn
    public void push(int x) {
        stackIn.push(x);
    }
    
    public int pop() {
        EmptyStackIn();
        return stackOut.pop();
    }
    
    public int peek() {
        EmptyStackIn();
        return stackOut.peek();
    }
    
    public boolean empty() {
        return stackIn.isEmpty() && stackOut.isEmpty();
    }

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

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

  1. 用队列实现栈 leetcode.com/problems/im…

思路:用两个队列的话还是比较好想的,就是push的时候往一个队列中加,栈pop的时候,把队列中刚加进去的这个数的前面几个数都放到另一个队列中,只留最后一个元素,然后再把另一个队列的元素倒回来

还有一种比较巧妙的就是用一个队列也是可以的,就是把辅助队列里的元素加到这个队列尾部就行了

class MyStack {
    //q1作为主要的队列,其元素排列顺序和出栈顺序相同
    Deque<Integer> q1 = new ArrayDeque<>();
    Deque<Integer> q2 = new ArrayDeque<>();

    public MyStack() {

    }
    //在加入元素时先将q1中的元素依次出栈压入q2,然后将新加入的元素压入q1,再将q2中的元素依次出栈压入q1
    public void push(int x) {
        while (q1.size() > 0) {
            q2.add(q1.poll());
        }
        q1.add(x);
        while (q2.size() > 0) {
            q1.add(q2.poll());
        }
    }

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

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

    public boolean empty() {
        return q1.isEmpty();
    }
}
  1. 有效的括号 leetcode.com/problems/va… 思路:就是用一个栈,如果是把左括号加入栈然后判断的话代码会复杂一点,如果是碰到左括号加入右括号,然后直接和栈顶元素比较的话,会简单一点
class Solution {
    public boolean isValid(String s) {
        Deque<Character> stack = new LinkedList<>();
        // 遍历字符串,碰到左括号就把对应的右括号加入栈
        for (int i = 0; i < s.length(); i++) {
            Character c = s.charAt(i);
            if (c == '(') stack.push(')');
            else if (c == '{') stack.push('}');
            else if (c == '[') stack.push(']');
            // 碰到右括号就和栈顶比较看是否能消除
            else if (c == stack.peek()) stack.pop();
            else return false;
        }
        return stack.isEmpty();      
}
}
  1. 删除字符串中的所有相邻重复项 leetcode.com/problems/re…

思路:这道题使用栈还是比较简单,把元素挨个入栈就行,判断当前元素和栈顶元素是否相同,如果相同就把栈顶元素pop,否则push

class Solution {
    public String removeDuplicates(String s) {
        Deque<Character> stack = new LinkedList<>();
        // char不能和null比较所以用包装类
        Character c;
        for (int i = 0; i < s.length(); i++) {
            c = s.charAt(i);
            // 跟栈顶元素比较
            if (c == stack.peek()) {
                stack.pop();
            } else {
                stack.push(c);
            }
        }
         String str = "";
        //剩余的元素即为不重复的元素
        while (!stack.isEmpty()) {
            str = stack.pop() + str;
        }
        return str;
    }
}

ArrayDeque会比LinkedList在除了删除元素这一点外会快一点 参考:stackoverflow.com/questions/6…