716、最大栈

  1. 题目
    1. 示例:
  2. 分析
    1. 栈+优先队列
    2. 最大堆

题目

设计一个最大栈数据结构,既支持栈操作,又支持查找栈中最大元素。

实现 MaxStack 类:

  • MaxStack() 初始化栈对象
  • void push(int x) 将元素 x 压入栈中。
  • int pop() 移除栈顶元素并返回这个元素。
  • int top() 返回栈顶元素,无需移除。
  • int peekMax() 检索并返回栈中最大元素,无需移除。
  • int popMax() 检索并返回栈中最大元素,并将其移除。如果有多个最大元素,只要移除 最靠近栈顶 的那个。

示例:

输入
["MaxStack", "push", "push", "push", "top", "popMax", "top", "peekMax", "pop", "top"]
[[], [5], [1], [5], [], [], [], [], [], []]
输出
[null, null, null, null, 5, 5, 1, 5, 1, 5]

解释
MaxStack stk = new MaxStack();
stk.push(5);   // [5] - 5 既是栈顶元素,也是最大元素
stk.push(1);   // [5, 1] - 栈顶元素是 1,最大元素是 5
stk.push(5);   // [5, 1, 5] - 5 既是栈顶元素,也是最大元素
stk.top();     // 返回 5,[5, 1, 5] - 栈没有改变
stk.popMax();  // 返回 5,[5, 1] - 栈发生改变,栈顶元素不再是最大元素
stk.top();     // 返回 1,[5, 1] - 栈没有改变
stk.peekMax(); // 返回 5,[5, 1] - 栈没有改变
stk.pop();     // 返回 1,[5] - 此操作后,5 既是栈顶元素,也是最大元素
stk.top();     // 返回 5,[5] - 栈没有改变

提示:

  • $-10^7 <= x <= 10^7$
  • 最多调用 104 次 push、pop、top、peekMax 和 popMax
  • 调用 pop、top、peekMax 或 popMax 时,栈中 至少存在一个元素

**进阶: **

试着设计解决方案:调用 top 方法的时间复杂度为 $O(1)$ ,调用其他方法的时间复杂度为 $O(logn)$。

分析

1、记录最大值节点的上下文位置
2、维护一个优先队列,从大到小记录给个节点
3、使用最大堆

栈+优先队列

    class MaxStack {
        PriorityQueue<Node> p;
        Node head;
        Node tail;
        int idx;

        public MaxStack() {
            p = new PriorityQueue<>((o1, o2) -> (o2.v == o1.v ? o2.idx - o1.idx : o2.v - o1.v));
            head = new Node();
            tail = new Node();
            head.next = tail;
            tail.pre = head;
            idx = 0;
        }

        public void push(int x) {
            Node next = head.next;
            Node node = new Node(x, idx++);
            head.next = node;
            node.pre = head;
            node.next = next;
            next.pre = node;
            p.offer(node);
        }

        public int pop() {
            Node node = head.next;
            Node next = node.next;
            head.next = next;
            next.pre = head;
            node.pre = node.next = null;
            return node.v;
        }

        public int top() {
            return head.next.v;
        }

        public int peekMax() {
            while (!p.isEmpty()&&p.peek().pre == null && p.peek().next == null) p.poll();
            return p.peek().v;
        }

        public int popMax() {
            peekMax();
            Node node = p.poll();
            Node pre = node.pre;
            Node suf = node.next;
            pre.next = suf;
            suf.pre = pre;
            return node.v;
        }

        class Node {
            int v;
            int idx;
            Node pre;
            Node next;

            public Node(int x, int idx) {
                this.v = x;
                this.idx = idx;
            }

            public Node() {
            }
        }
    }

/**
 * Your MaxStack object will be instantiated and called as such:
 * MaxStack obj = new MaxStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.peekMax();
 * int param_5 = obj.popMax();
 */

最大堆

class MaxStack {

    private TreeSet<int[]> stack;
    private TreeSet<int[]> values;
    private int cnt;

    public MaxStack() {
        Comparator<int[]> comp = (a, b) -> {
            return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
        };
        stack = new TreeSet<>(comp);
        values = new TreeSet<>(comp);
        cnt = 0;
    }

    public void push(int x) {
        stack.add(new int[] { cnt, x });
        values.add(new int[] { x, cnt });
        cnt++;
    }

    public int pop() {
        int[] pair = stack.pollLast();
        values.remove(new int[] { pair[1], pair[0] });
        return pair[1];
    }

    public int top() {
        return stack.last()[1];
    }

    public int peekMax() {
        return values.last()[0];
    }

    public int popMax() {
        int[] pair = values.pollLast();
        stack.remove(new int[] { pair[1], pair[0] });
        return pair[0];
    }
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com

💰

Title:716、最大栈

Count:850

Author:攀登

Created At:2024-07-04, 11:31:04

Updated At:2024-07-04, 11:58:15

Url:http://jiafeimao-gjf.github.io/2024/07/04/716%E3%80%81%E6%9C%80%E5%A4%A7%E6%A0%88/

Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.

×

Help us with donation