栈和队列题型

模拟栈和队列

  • 232.用栈实现队列
class MyQueue {
    Deque<Integer> stack1;
    Deque<Integer> stack2;
    public MyQueue() {
        stack1 = new LinkedList<>();
        stack2 = new LinkedList<>();
    }
    /*
        压栈没有空栈的情况
    */
    public void push(int x) {
        stack1.offerFirst(x);
    }
    /*
        弹栈有空栈的情况
     */
    public int pop() {
        if (!stack2.isEmpty()) {
            return stack2.pollFirst();
        } else {
            while (!stack1.isEmpty()) {
                stack2.offerFirst(stack1.pollFirst());
            }
            return stack2.pollFirst();
        }
    }
    
    public int peek() {
        if (!stack2.isEmpty()) {
            return stack2.peekFirst();
        } else {
            while (!stack1.isEmpty()) {
                stack2.offerFirst(stack1.pollFirst());
            }
            return stack2.peekFirst();
        }
    }
    
    public boolean empty() {
        return stack1.isEmpty() && stack2.isEmpty();
    }
}

/**
 * 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();
 */
  • 队列模拟栈
class MyStack {
    Queue<Integer> que1;
    Queue<Integer> que2;
    public MyStack() {
        que1 = new LinkedList<>();
        que2 = new LinkedList<>();
    }
    /*
        压栈不涉及空队列的问题
     */
    public void push(int x) {
        que1.offer(x);
    }
    /**
        弹栈涉及空队列
     */
    public int pop() {
        while (que1.size() != 1) {
            que2.offer(que1.poll());
        }
        while (!que2.isEmpty()) {
            que1.offer(que2.poll());
        }
        return que1.poll();
    }
    
    public int top() {
        while (que1.size() != 1) {
            que2.offer(que1.poll());
        }
        int res = que1.peek();
        que2.offer(que1.poll());
        while (!que2.isEmpty()) {
            que1.offer(que2.poll());
        }
        return res;  
    }
    
    public boolean empty() {
        return que1.isEmpty() && que2.isEmpty();
    }
}

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

用栈进行匹配的问题

  • 20 有效的括号
class Solution {
    public boolean isValid(String s) {
        Deque<Character> stack = new LinkedList<>();
        for (int i = 0; i < s.length(); i++) {
            if (stack.isEmpty()) {
                stack.offerFirst(s.charAt(i));
            } else {
                if (check(stack.peekFirst(), s.charAt(i))) {
                    stack.pollFirst();
                } else {
                    stack.offerFirst(s.charAt(i));
                }
            }
        }

        if (stack.isEmpty()) {
            return true;
        } 
        return false;
    }

    boolean check(Character c1, Character c2) {
        if (c1 == '[') {
            if (c2 == ']') {
                return true;
            }
        } else if (c1 == '{') {
            if (c2 == '}') {
                return true;
            }
        } else if (c1 == '(') {
            if (c2 == ')') {
                return true;
            }
        }
        return false;
    }
}
  • 1047 删除字符串的重复项
class Solution {
    public String removeDuplicates(String s) {
        Deque<Character> stack = new LinkedList<>();

        for (int i = 0; i < s.length(); i++) {
            if (stack.isEmpty()) {
                stack.offerFirst(s.charAt(i));
            } else {
                if (stack.peekFirst() == s.charAt(i)) {
                    stack.pollFirst();
                } else {
                    stack.offerFirst(s.charAt(i));
                }
            }
        }

        char[] chars = new char[stack.size()];
        for (int i = chars.length - 1; i >= 0; i--) {
            chars[i] = stack.pollFirst();
        }
        return new String(chars);
    }
}
  • 150 逆波兰表达式
class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> stack = new LinkedList<>();
        for (String s : tokens) {
            if (stack.isEmpty()) {
                Integer i = Integer.valueOf(s);
                stack.offerFirst(i);
            } else {
                if (s.equals("+")) {
                    Integer a = stack.pollFirst();
                    Integer b = stack.pollFirst();
                    stack.offerFirst(b + a);
                } else if (s.equals("-")) {
                    Integer a = stack.pollFirst();
                    Integer b = stack.pollFirst();     
                    stack.offerFirst(b - a);           
                } else if (s.equals("*")) {
                    Integer a = stack.pollFirst();
                    Integer b = stack.pollFirst();     
                    stack.offerFirst(b * a);                         
                } else if (s.equals("/")) {
                    Integer a = stack.pollFirst();
                    Integer b = stack.pollFirst();     
                    stack.offerFirst(b / a);    
                } else {
                    Integer i = Integer.valueOf(s);
                    stack.offerFirst(i);
                }
        }
        }
        return stack.peekFirst();
    }
}

单调队列

  • 239 滑动窗口最大值
class Solution {
    /*
        单调队列要用双端队列来实现
     */
    Deque<Integer> que = new LinkedList<>();
    public int[] maxSlidingWindow(int[] nums, int k) {
        int[] res = new int[nums.length - k + 1];
        int count = 0;
        for (int i = 0; i < k; i++) {
            push(nums[i]);
        }
        res[count++] = max();
        for (int i = k; i < nums.length; i++) {
            /**
                先弹再加,要是先加再弹就会弹错
             */
            pop(nums[i - k]);
            push(nums[i]);
            
            res[count++] = max();
        }   
        return res;
    }


    /**
        维护一个单调队列
     */
    void push(int x) {
        /*
            如果新进入队列的值比队列入口的值大的话,删除入口元素。
            不能和出口元素比较,因为插入元素的大小可能会在出口元素和入口元素之间
         */
        while (!que.isEmpty() && que.peekLast() < x) {
            que.pollLast();
        } 
            que.offerLast(x);
    }
    /*
        弹出就弹出一个即可,因为可能又多个最大值
     */

    void pop(int x) {
        if (!que.isEmpty() && x == que.peekFirst()) {
            que.poll();
        }
    }

    int max() {
        return que.peekFirst();
    }
    
}

优先队列(大顶堆or小顶堆)

  • 347 前k个高频元素
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> hashMap = new HashMap<>();
        for (Integer i : nums) {
            hashMap.put(i, hashMap.getOrDefault(i, 0) + 1);
        }
        /*
            优先队列中放的是entry对象,将出现次数和值对应起来
         */
        Set<Map.Entry<Integer, Integer>> set = hashMap.entrySet();
        /**
            构建小顶堆(先弹出小的,即小的数在队头,大顶堆相反)
            从小到大的排序比较方式构成小顶堆
         */
        PriorityQueue<Map.Entry<Integer,Integer>> que = new PriorityQueue<>(
            (o1, o2)-> o1.getValue() - o2.getValue());
        for (Map.Entry<Integer, Integer> entry : set) {
            que.offer(entry);
            if (que.size() > k) {
                que.poll();
            }
        }

        /**
            获取结果
         */
        int[] res = new int[k];
        for (int i = k - 1; i >= 0; i--) {
            res[i] = que.poll().getKey();
        }
        return res;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值