给定一个整数数组 nums,处理以下类型的多个查询:
计算索引 left 和 right (包含 left 和 right)之间的 nums 元素的 和 ,其中 left <= right
实现 NumArray 类:
NumArray(int[] nums) 使用数组 nums 初始化对象
int sumRange(int i, int j) 返回数组 nums 中索引 left 和 right 之间的元素的 总和 ,包含 left 和 right 两点(也就是 nums[left] + nums[left + 1] + … + nums[right] )
示例 1:
输入:
["NumArray", "sumRange", "sumRange", "sumRange"]
[[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]
输出:
[null, 1, -1, -3]
解释:
NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);
numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3)
numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1))
numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1))
sumRange 算法的功能即实现 nums[left] + nums[left + 1] + … + nums[right] 的求和,返回求和结果
class NumArray {
private int[] nums;
public NumArray(int[] nums) {
this.nums = nums;
}
public int sumRange(int left, int right) {
int sum = 0;
for (int i = left; i <= right; i++) {
sum += nums[i];
}
return sum;
}
}
数组 nuns 索引范围 [i,j] 求和的计算公式:
计算 sumRange(i,j) 转化为计算数组 nums 在下标 j 和下标 i-1 的前缀和,然后计算两个前缀和的差:sumRange(i,j) = sum(0,j) - sum(0,i-1)
比如有数组nums = [-2, 0, 3, -5, 2, -1]
新数组 sums, 令 sums[0] = 0
sums[1] = nums[0] = -2
sums[2] = sums[1] + nums[1] = -2
sums[3] = sums[2] + nums[2] = 1
sums[4] = sums[3] + nums[3] = -4
sums[5] = sums[4] + nums[4] = -2
suns[6] = snms[5] + nums[5] = -3
sums = [0,-2,-2,1,-4,-2,-3]
sumRange(0,2) = (-2) + 0 + 3 = 1 = sums[3] - sums[0] = 1 - 0 = 1
sumRange(2,5) = 3 + (-5) + 2 + (-1) = -1 = sums[6] - sums[2] = (-3) - (-2) = -1
sumRange(0,5) = (-2) + 0 + 3 + (-5) + 2 + (-1)= -3 = sums[6] - sums[0] = (-3) - (0) = -3
这就是前缀和思想:
具体实现方面,假设数组 nums 的长度为 n,创建长度为 n+1 的前缀和数组 sums,对于 0 ≤ i < n 都有 sums[i+1]=sums[i]+nums[i],则当 0 < i ≤ n 时,sums[i] 表示数组 nums 从下标 0 到下标 i−1 的前缀和
class NumArray {
int[] sums;
public NumArray(int[] nums) {
sums = new int[nums.length + 1];
for (int i = 0; i < nums.length; i++) {
sums[i + 1] = sums[i] + nums[i];
}
}
public int sumRange(int i, int j) {
return sums[j + 1] - sums[i];
}
}
class NumArray {
int[] sums;
public NumArray(int[] nums) {
sums = new int[nums.length + 1];
for (int i = 1; i < sums.length; i++) {
sums[i] = sums[i - 1] + nums[i - 1];
}
}
public int sumRange(int i, int j) {
return sums[j + 1] - sums[i];
}
}