单调队列 Monotonic Queue / 单调栈 Monotonic Stack

2018-11-16 22:45:48

一、单调队列 Monotone Queue

  • 239. Sliding Window Maximum

问题描述:

问题求解:

本题是一个经典的可以使用双端队列或者说单调队列完成的题目,具体来说,就是通过双端队列将可能的最大值维护起来。

    public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums == null || nums.length < k || k == 0) return new int[0];
        Deque<Integer> q = new LinkedList<>();
        int[] res = new int[nums.length - k + 1];
        for (int i = 0; i < nums.length; i++) {
            while (!q.isEmpty() && q.getFirst() < nums[i]) q.pollFirst();
            q.addFirst(nums[i]);
            if (i >= k - 1) {
                res[i - k + 1] = q.getLast();
                if (q.getLast() == nums[i - k + 1]) q.pollLast();
            }
        }
        return res;
    }

  

二、单调栈 Monotone Stack

什么是Monotonic Stack?

答:从栈顶到栈底是按照单调顺序排列的。

  • 739. Daily Temperatures

问题描述:

问题求解:

维护一个从栈顶到栈底单调递增的栈。

从末尾向前遍历,如果当前的数值比栈顶的数值要大的话,那么显然更小的数值是不再需要的了,直接pop即可。

    public int[] dailyTemperatures(int[] T) {
        int[] res = new int[T.length];
        Stack<int[]> stack = new Stack<>();
        for (int i = T.length - 1; i >= 0; i--) {
            while (!stack.isEmpty() && stack.peek()[0] <= T[i]) stack.pop();
            res[i] = stack.isEmpty() ? 0 : stack.peek()[1] - i;
            stack.push(new int[]{T[i], i});
        }
        return res;
    }

 

  • 1019. Next Greater Node In Linked List

问题描述:

问题求解:

    public int[] nextLargerNodes(ListNode head) {
        List<Integer> nums = new ArrayList<>();
        for (ListNode cur = head; cur != null; cur = cur.next) {
            nums.add(cur.val);
        }
        int[] res = new int[nums.size()];
        Stack<Integer> stack = new Stack<>();
        for (int i = nums.size() - 1; i >= 0; i--) {
            while (!stack.isEmpty() && stack.peek() <= nums.get(i)) stack.pop();
            res[i] = stack.isEmpty() ? 0 : stack.peek();
            stack.push(nums.get(i));
        }
        return res;
    }

 

  • 901. Online Stock Span

问题描述:

问题求解:

public class StockSpanner {
    Stack<int[]> stack;
    int idx;

    public StockSpanner() {
        stack = new Stack<>();
        stack.push(new int[]{Integer.MAX_VALUE, -1});
        idx = 0;
    }

    public int next(int price) {
        while (stack.peek()[1] <= price) stack.pop();
        int res = idx - stack.peek()[1];
        stack.push(new int[]{price, idx});
        idx++;
        return res;
    }
}

  

 

 

  

 

转载于:https://www.cnblogs.com/hyserendipity/p/9972221.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单调单调队列都是常用的数据结构,用于解决特定的问题。它们的特性可以用来估计时间复杂度。 **单调Monotonic Stack)**:单调在处理一些需要按特定顺序访问元素的问题时非常有用。如果一个的元素值在遍历过程中保持单调递减或递增(即,对于中的每个元素,其后的元素都小于或大于它),那么这个就被称为单调单调的时间复杂度通常取决于问题的特性,但通常在最坏情况下是O(n),其中n是问题的规模。这是因为每次访问一个新的元素,都需要将其压入中,这需要O(1)时间,但压入元素后的所有后续操作(例如,弹出元素和查看顶元素)都需要遍历整个,这需要O(n)时间。 **单调队列Monotonic Queue)**:单调队列通常用于解决需要维护一个单调序列的问题。如果一个队列的元素值在遍历过程中保持单调递增或递减(即,对于队列中的每个元素,它后面的所有元素都小于或大于它),那么这个队列就被称为单调队列。对于单调队列,如果我们遍历一次队列并将结果放入一个新的列表中,那么时间复杂度就是O(n)。这是因为我们需要遍历整个队列来获取结果,而这个过程需要O(n)时间。然而,如果我们使用一个单调来维护这个队列,那么时间复杂度就可以降低到O(n log k),其中k是队列中元素的数量。 以上是对这两种数据结构的时间复杂度的基本理解,但请注意,具体的时间复杂度可能会根据问题的具体情况和使用的算法有所不同。在处理实际问题时,最好能够理解问题本身的特点,选择最合适的数据结构和算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值