題目
概述:給定一個數組,求該數組的所有連續子數組最小元素的和
輸入:整數數組,長度范圍[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;
}
}
}