题目

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<Integer> valueStack = new Stack<>();Stack<Integer> 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;}
}

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

  1. LeetCode 907. 子数组的最小值之和(单调栈)

    文章目录 1. 题目 2. 解题 1. 题目 给定一个整数数组 A,找到 min(B) 的总和,其中 B 的范围为 A 的每个(连续)子数组. 由于答案可能很大,因此返回答案模 10^9 + 7. 示 ...

  2. 【LeetCode】Maximum Product Subarray 求连续子数组使其乘积最大

    Add Date 2014-09-23 Maximum Product Subarray Find the contiguous subarray within an array (containin ...

  3. LeetCode 2104. 子数组范围和(单调栈)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个整数数组 nums .nums 中,子数组的 范围 是子数组中最大元素和最小元素的差值. 返回 nums 中 所有 子数组范围的 和 . 子数组是 ...

  4. LeetCode 1063. 有效子数组的数目(单调栈)

    文章目录 1. 题目 2. 解题 1. 题目 给定一个整数数组 A,返回满足下面条件的 非空.连续 子数组的数目: 子数组中,最左侧的元素不大于其他元素. 示例 1: 输入:[1,4,2,5,3] 输 ...

  5. leetcode 643. Maximum Average Subarray I | 643. 子数组最大平均数 I(Java)

    题目 https://leetcode-cn.com/problems/maximum-average-subarray-i/ 题解 滑动窗口解法,示意图: 另外,double 计算比 int 要慢, ...

  6. Leetcode滑窗系列(java):643. 子数组最大平均数 I

    Leetcode滑窗系列(java):643. 子数组最大平均数 I(新手小白仅供参考) 题目来源 leetcode 题目描述 个人思路 创建一个滑窗,将其值的和作为作为判断基准 然后滑窗的左右边界各 ...

  7. 【LeetCode】剑指 Offer 42. 连续子数组的最大和

    [LeetCode]剑指 Offer 42. 连续子数组的最大和 文章目录 [LeetCode]剑指 Offer 42. 连续子数组的最大和 一.动态规划 一.动态规划 状态定义 设动态规划列表 dp ...

  8. LeetCode 2302. 统计得分小于 K 的子数组数目(前缀和+二分查找)

    文章目录 1. 题目 2. 解题 1. 题目 一个数组的 分数 定义为数组之和 乘以 数组的长度. 比方说,[1, 2, 3, 4, 5] 的分数为 (1 + 2 + 3 + 4 + 5) * 5 = ...

  9. 数组最大可以开多大_每日算法系列【LeetCode 689】三个无重叠子数组的最大和

    题目描述 给定数组 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为 ,我们要使这 个项的和最大化. 返回每个区间起始索引的列表(索引从 0 开始).如果有多个结果,返回字典序最小 ...

最新文章

  1. VirtualBox的四种网络连接方式
  2. 前端中会用到的设计模式之单一职责原则
  3. 浅谈压缩感知(三十一):压缩感知重构算法之定点连续法FPC
  4. Spring 通过工厂方法(Factory Method)来配置bean
  5. 【虚拟化实战】容灾设计之三Stretched Cluster
  6. VMware Workstation Pro通过ISO系统镜像安装ubuntu-18.04.2
  7. css --- [练手小项目]样式小结(字体、颜色的语义 清除浮动的使用)
  8. mysql中使用CONCAT 实现拼接
  9. [css] 有哪些标签是不支持伪元素的?
  10. 数值计算方法(七)——两种消去法求解线性方程组
  11. html密码框输入内容隐藏,密码框显示提示文字的功能实现
  12. div section article区分--20150227
  13. 英特尔逆天原型机:在 Android 上跑 Debian
  14. Phoenix使用注意事项以及跟标准sql的不同
  15. 根据ASCII码值排序
  16. linux内存使用率如何查看,linux内存使用率 linux查看内存
  17. 计算机共享网络热点,手把手教你在win7电脑中设置共享wifi热点
  18. U盘启动盘制作与ISO分享
  19. Qt 官方例子 Callout Example
  20. mysql查看数据库状态

热门文章

  1. CodeForces - 1301F Super Jaber(bfs)
  2. CodeForces - 603C Lieges of Legendre(博弈+找规律)
  3. 2019ICPC(银川) - Take Your Seat(概率公式)
  4. 南通工学院计算机97级,2021年南通理工学院录取结果查询网址入口及录取结果公布时间...
  5. android 单位转换工具,Android单位转换----常用单位转换工具类
  6. router vue 动态改变url_vue动态路由
  7. 使用docker构建并测试一个基于Sinatra的Web应用程序
  8. AJAX DELETE
  9. C++的Json解析库:jsoncpp和boost
  10. PyCairo 中的透明度