栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

leetcode 907. Sum of Subarray Minimums | 907. 子数组的最小值之和(单调栈)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

leetcode 907. Sum of Subarray Minimums | 907. 子数组的最小值之和(单调栈)

题目

https://leetcode.com/problems/sum-of-subarray-minimums/

题解

单调栈问题。参考左神算法课:https://ke.qq.com/webcourse/3067253/103187834#taid=10646309101817205&vid=5285890813430715450

相当于找当前元素属于哪些子序列的最小值,如下图,以 10 位置的 7 为例,它可以是以下标 6~10 任意一个作为开始,到下标 10~14 任意一个作为结束的所有 5*5=25 个子数组的最小值,所以,以 7 为最小值的 subarray sum = 5*5*7。


需要注意的是出现相等数字时候的情况,具体表现为当遇到相等数字时,不重复计算即可。可以听左神讲的,也可以自己画一下,试一下就懂了。

class Solution {
    public static final int MOD = (int) (Math.pow(10, 9) + 7);

    public int sumSubarrayMins(int[] arr) {
        int L = arr.length;
        // 找左边第一个【小于等于】h[i]的数
        // 从右向左遍历,维护单调增栈,小/等数h[i]不断将大数h[j]弹出,则h[i]左边第一个小于h[i]的数为h[j]
        Stack valueStack = new Stack<>();
        Stack indexStack = new Stack<>();
        int[] leftIndex = new int[L]; // i左边第一个小于i的数的下标
        Arrays.fill(leftIndex, -1);
        for (int i = L - 1; i >= 0; i--) {
            while (!valueStack.isEmpty() && valueStack.peek() >= arr[i]) {
                leftIndex[indexStack.pop()] = i;
                valueStack.pop();
            }
            valueStack.push(arr[i]);
            indexStack.push(i);
        }
        // 找右边第一个【小于】h[i]的数
        // 从左向右遍历,维护单调不减栈
        valueStack = new Stack<>();
        indexStack = new Stack<>();
        int[] rightIndex = new int[L]; // i右边第一个小于i的数的下标
        Arrays.fill(rightIndex, L);
        for (int i = 0; i < L; i++) {
            while (!valueStack.isEmpty() && valueStack.peek() > arr[i]) {
                rightIndex[indexStack.pop()] = i;
                valueStack.pop();
            }
            valueStack.push(arr[i]);
            indexStack.push(i);
        }

        long result = 0;
        for (int i = 0; i < L; i++) {
            int fromRange = i - leftIndex[i];
            int toRange = rightIndex[i] - i;
            result += (long)fromRange * toRange * arr[i];
            result %= MOD;
        }
        return (int) result;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/309855.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号