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<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. 子数组的最小值之和(单调栈)相关推荐
- LeetCode 907. 子数组的最小值之和(单调栈)
文章目录 1. 题目 2. 解题 1. 题目 给定一个整数数组 A,找到 min(B) 的总和,其中 B 的范围为 A 的每个(连续)子数组. 由于答案可能很大,因此返回答案模 10^9 + 7. 示 ...
- 【LeetCode】Maximum Product Subarray 求连续子数组使其乘积最大
Add Date 2014-09-23 Maximum Product Subarray Find the contiguous subarray within an array (containin ...
- LeetCode 2104. 子数组范围和(单调栈)
文章目录 1. 题目 2. 解题 1. 题目 给你一个整数数组 nums .nums 中,子数组的 范围 是子数组中最大元素和最小元素的差值. 返回 nums 中 所有 子数组范围的 和 . 子数组是 ...
- LeetCode 1063. 有效子数组的数目(单调栈)
文章目录 1. 题目 2. 解题 1. 题目 给定一个整数数组 A,返回满足下面条件的 非空.连续 子数组的数目: 子数组中,最左侧的元素不大于其他元素. 示例 1: 输入:[1,4,2,5,3] 输 ...
- leetcode 643. Maximum Average Subarray I | 643. 子数组最大平均数 I(Java)
题目 https://leetcode-cn.com/problems/maximum-average-subarray-i/ 题解 滑动窗口解法,示意图: 另外,double 计算比 int 要慢, ...
- Leetcode滑窗系列(java):643. 子数组最大平均数 I
Leetcode滑窗系列(java):643. 子数组最大平均数 I(新手小白仅供参考) 题目来源 leetcode 题目描述 个人思路 创建一个滑窗,将其值的和作为作为判断基准 然后滑窗的左右边界各 ...
- 【LeetCode】剑指 Offer 42. 连续子数组的最大和
[LeetCode]剑指 Offer 42. 连续子数组的最大和 文章目录 [LeetCode]剑指 Offer 42. 连续子数组的最大和 一.动态规划 一.动态规划 状态定义 设动态规划列表 dp ...
- LeetCode 2302. 统计得分小于 K 的子数组数目(前缀和+二分查找)
文章目录 1. 题目 2. 解题 1. 题目 一个数组的 分数 定义为数组之和 乘以 数组的长度. 比方说,[1, 2, 3, 4, 5] 的分数为 (1 + 2 + 3 + 4 + 5) * 5 = ...
- 数组最大可以开多大_每日算法系列【LeetCode 689】三个无重叠子数组的最大和
题目描述 给定数组 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为 ,我们要使这 个项的和最大化. 返回每个区间起始索引的列表(索引从 0 开始).如果有多个结果,返回字典序最小 ...
最新文章
- VirtualBox的四种网络连接方式
- 前端中会用到的设计模式之单一职责原则
- 浅谈压缩感知(三十一):压缩感知重构算法之定点连续法FPC
- Spring 通过工厂方法(Factory Method)来配置bean
- 【虚拟化实战】容灾设计之三Stretched Cluster
- VMware Workstation Pro通过ISO系统镜像安装ubuntu-18.04.2
- css --- [练手小项目]样式小结(字体、颜色的语义 清除浮动的使用)
- mysql中使用CONCAT 实现拼接
- [css] 有哪些标签是不支持伪元素的?
- 数值计算方法(七)——两种消去法求解线性方程组
- html密码框输入内容隐藏,密码框显示提示文字的功能实现
- div section article区分--20150227
- 英特尔逆天原型机:在 Android 上跑 Debian
- Phoenix使用注意事项以及跟标准sql的不同
- 根据ASCII码值排序
- linux内存使用率如何查看,linux内存使用率 linux查看内存
- 计算机共享网络热点,手把手教你在win7电脑中设置共享wifi热点
- U盘启动盘制作与ISO分享
- Qt 官方例子 Callout Example
- mysql查看数据库状态
热门文章
- CodeForces - 1301F Super Jaber(bfs)
- CodeForces - 603C Lieges of Legendre(博弈+找规律)
- 2019ICPC(银川) - Take Your Seat(概率公式)
- 南通工学院计算机97级,2021年南通理工学院录取结果查询网址入口及录取结果公布时间...
- android 单位转换工具,Android单位转换----常用单位转换工具类
- router vue 动态改变url_vue动态路由
- 使用docker构建并测试一个基于Sinatra的Web应用程序
- AJAX DELETE
- C++的Json解析库:jsoncpp和boost
- PyCairo 中的透明度