6、栈与队列

代码随想录
LeetCode 题解

1、用栈实现队列

232 - 用栈实现队列

public class MyQueue {

    private Stack<Integer> stack1; // 用来添加元素
    private Stack<Integer> stack2; // 用来缓存部分已经排好的元素
    private int front; // 需要保证 front 是 stack1 中最先进来的元素

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

    public void push(int x) {
        if (stack1.isEmpty()) front = x;
        stack1.push(x);
    }

    // [123 -> 123]
    public int pop() {
        if (!stack2.isEmpty()) return stack2.pop();
        while (stack1.size() != 1) stack2.push(stack1.pop());
        return stack1.pop();
    }

    public int peek() {
        if (!stack2.isEmpty()) return stack2.peek();
        return front;
    }

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

2、用队列实现栈

225 - 用队列实现栈

public class MyStack {

    private Queue<Integer> queue;

    public MyStack() {
        queue = new LinkedList<>();
    }

    // 3214 -> 4321
    public void push(int x) {
        queue.add(x);
        for (int i = 0; i < queue.size() - 1; i++) queue.add(queue.remove());
    }

    public int pop() {
        return queue.remove();
    }

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

    public boolean empty() {
        return queue.isEmpty();
    }
}

3、有效的括号

20 - 有效的括号

public boolean isValid(String s) {
    char[] arr = s.toCharArray();
    Deque<Character> stack = new ArrayDeque<>();

    for (char c : arr) {
        if (c == '(' || c == '[' || c == '{') stack.addLast(c);
        else {
            if (stack.isEmpty()) return false;
            char top = stack.removeLast();
            if (top == '(' && c != ')') return false;
            if (top == '[' && c != ']') return false;
            if (top == '{' && c != '}') return false;
        }
    }

    return stack.isEmpty();
}

4、删除字符串中的所有相邻重复项

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

public String removeDuplicates(String s) {
    Deque<Character> deque = new LinkedList<>();
    char[] arr = s.toCharArray();

    for (char c : arr) {
        if (deque.isEmpty()) deque.addLast(c);
        else {
            if (c != deque.getLast()) deque.addLast(c);
            else deque.removeLast();
        }
    }

    StringBuilder sb = new StringBuilder();
    while (!deque.isEmpty()) sb.append(deque.removeFirst());
    return sb.toString();
}

5、逆波兰表达式求值

150 - 逆波兰表达式求值

public int evalRPN(String[] tokens) {
    Deque<Integer> stack = new ArrayDeque<>();

    for (String token : tokens) {
        if (!isFh(token)) stack.addLast(Integer.valueOf(token));
        else {
            int v2 = stack.removeLast();
            int v1 = stack.removeLast();
            switch (token) {
                case "+":
                    stack.addLast(v1 + v2);
                    break;
                case "-":
                    stack.addLast(v1 - v2);
                    break;
                case "*":
                    stack.addLast(v1 * v2);
                    break;
                case "/":
                    stack.addLast(v1 / v2);
                    break;
            }
        }
    }

    return stack.removeLast();
}

private boolean isFh(String str) {
    return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/");
}

6、滑动窗口最大值

239 - 滑动窗口最大值

public static int[] maxSlidingWindow(int[] nums, int k) {
    if (k == 1) return nums;
    if (k >= nums.length) {
        int max = nums[0];
        for (int i = 1; i < nums.length; i++) max = Math.max(max, nums[i]);
        return new int[]{max};
    }

    int[] res = new int[nums.length - k + 1];
    int index = 0;

    // 从大到小的单调队列, 存储的是索引
    // 窗口缩小时, 队首的值会依次成为窗口内的最大值
    // 新元素 cur 入队时, 队尾中值 <= cur 值需要依次弹出
    Deque<Integer> deque = new LinkedList<>();
    for (int r = 0; r < nums.length; r++) {
        int cur = nums[r];
        while (!deque.isEmpty() && nums[deque.getLast()] <= cur) deque.removeLast();
        deque.addLast(r);

        if (deque.getFirst() < r - k + 1) deque.removeFirst();

        if (r >= k - 1) res[index++] = nums[deque.getFirst()];
    }

    return res;
}

7、前 K 个高频元素

347 - 前 K 个高频元素

public class Solution {

    private class Node {
        public int num;
        public int count;

        public Node(int num, int count) {
            this.num = num;
            this.count = count;
        }
    }

    public int[] topKFrequent(int[] nums, int k) {
        // 值 : 次数
        Map<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

        // 根据次数来比较的最大堆
        PriorityQueue<Node> maxHeap = new PriorityQueue<>((o1, o2) -> o2.count - o1.count);
        map.forEach((num, count) -> maxHeap.add(new Node(num, count)));

        int[] res = new int[k];
        for (int i = 0; i < k; i++) {
            res[i] = maxHeap.remove().num;
        }
        return res;
    }
}
posted @ 2023-05-29 15:41  lidongdongdong~  阅读(6)  评论(0编辑  收藏  举报