3427. 变长子数组求和
给你一个长度为 n
的整数数组 nums
。对于 每个 下标 i
(0 <= i < n
),定义对应的子数组 nums[start ... i]
(start = max(0, i - nums[i])
)。
返回为数组中每个下标定义的子数组中所有元素的总和。
子数组 是数组中的一个连续、非空 的元素序列。
示例 1:
输入:nums = [2,3,1]
输出:11
解释:
下标 i | 子数组 | 和 |
---|---|---|
0 | nums[0] = [2] | 2 |
1 | nums[0 ... 1] = [2, 3] | 5 |
2 | nums[1 ... 2] = [3, 1] | 4 |
总和 | 11 |
总和为 11 。因此,输出 11 。
示例 2:
输入:nums = [3,1,1,2]
输出:13
解释:
下标 i | 子数组 | 和 |
---|---|---|
0 | nums[0] = [3] | 3 |
1 | nums[0 ... 1] = [3, 1] | 4 |
2 | nums[1 ... 2] = [1, 1] | 2 |
3 | nums[1 ... 3] = [1, 1, 2] | 4 |
总和 | 13 |
总和为 13 。因此,输出为 13 。
提示:
1 <= n == nums.length <= 100
1 <= nums[i] <= 1000
/**
* 3427. 变长子数组求和
*/
public static int subarraySum(int[] nums) {
int[] s = new int[nums.length + 1];
// 初始化为0,方便对前缀求和
s[0] = 0;
int ans = 0;
for (int i = 0; i < nums.length; i++) {
// 根据题目求得子区间nums[start,i]
int start = Math.max(0, i - nums[i]);
// 前缀和求和
s[i + 1] = s[i] + nums[i];
// 利用前缀和快速计算区间内的和
ans += s[i + 1] - s[start];
}
return ans;
}