栈-N907-子数组的最小值之和
2019-04-27 本文已影响0人
三次元蚂蚁
题目
-
概述:给定一个数组,求该数组的所有连续子数组最小元素的和
-
输入:整数数组,长度范围[1, 30000]
-
输入子项:整数,范围[1, 30000]
-
输出:所有连续子数组最小元素的和对10^9+7取模
-
出处:https://leetcode-cn.com/problems/sum-of-subarray-minimums/
思路
-
由于需要记录之前子数组的最小值方便快速计算之后子数组的最小值,所以考虑用栈来实现
-
将数组元素依次入栈:
- 如果当前数组元素大于等于栈顶元素,则以当前元素为结尾的所有子数组之和等于以栈顶元素为结尾的所有子数组之和+当前元素
- 如果当前数组元素小于栈顶元素,则将栈中元素依次出栈,每出栈一次加上一次当前元素*相应倍数,记录出栈元素个数为相应倍数,直到当前数组元素大于等于栈顶元素,仍然沿用1方法计算
> 特别注意:相应倍数需要累加
代码
class Solution {
public int sumSubarrayMins(int[] A) {
LinkedList<Node> stack = new LinkedList<>();
int result = 0;
int mod = 1000000007;
int sum;
int coef;
Node top;
result += A[0];
stack.push(new Node(A[0], 1, A[0]));
for (int i = 1; i < A.length; ++i) {
sum = A[i];
coef = 1;
while (true) {
if (stack.isEmpty()) {
stack.push(new Node(A[i], coef, sum));
break;
}
top = stack.peek();
if (A[i] >= top.num) {
sum = (top.sum + sum) % mod;
stack.push(new Node(A[i], coef, sum));
break;
} else {
sum = (A[i] * top.coef + sum) % mod;
coef += top.coef;
stack.pop();
}
}
result = (result + sum) % mod;
}
return result;
}
private class Node {
int num;
int coef;
int sum;
public Node(int num, int coef, int sum) {
this.num = num;
this.coef = coef;
this.sum = sum;
}
}
}