问题描述
我正在解决 leetcode 中的子数组最小值总和问题。
问题描述 - 给定一个整数数组 arr,找到 min(b) 的总和,其中 b 的范围是 arr 的每个(连续)子数组。由于答案可能很大,返回模数 (10^9) + 7。
问题示例 -
输入:arr = [3,1,2,4]
输出:17
说明:
子数组是 [3],[1],[2],[4],[3,1],[1,2],[2,4],4]。
最小值为 3,4,1。 总和是 17。
我的解决方案 -
class Solution {
int MOD = 1000000007;
public int sumSubarrayMins(int[] arr) {
int sum = 0;
for(int i=0; i<arr.length; i++) {
int left = i;
int right = i;
while(left > 0 && arr[i] <= arr[left - 1]) {
left--;
}
while(right < arr.length - 1 && arr[i] < arr[right + 1]){
right++;
}
sum = sum + (((i - left + 1) * (right - i + 1)) * (arr[i]));
sum%=MOD;
}
return sum;
}
}
我的解决方案适用于所有测试用例,但最后一个输入数组非常大并且总和值将超过 mod 值。
我的输出:372485114
预期:667452382
我的 MOD 10^9 + 7 计算似乎有误,但我似乎无法弄清楚问题所在。
解决方法
我怀疑总和sum + (((i - left + 1) * (right - i + 1)) * (arr[i]))
正在溢出,因为它是作为 int
完成的。
将其更改为 long
(例如使用 ... + 1L...
或在乘法之前进行转换),并在转换回 int
之前进行取模(或使用 long sum
)。
最终,根据输入数字的范围,在添加之前还要计算(((i - left + 1) * (right - i + 1)) * (arr[i]))
的模数。