题目:
给定一个整数数组 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]
)
思路:前缀和
问:为什么要定义 s[0]=0,这样做有什么好处?
答:如果 left=0,要计算的子数组是一个前缀(从 a[0] 到 a[right]),我们要用 s[right+1] 减去 s[0]。如果不定义 s[0]=0,就必须特判 left=0 的情况了(读者可以试试)。通过定义 s[0]=0,任意子数组(包括前缀)都可以表示为两个前缀和的差。此外,如果 a 是空数组,定义 s[0]=0 的写法是可以兼容这种情况的。
代码:
class NumArray {
private int[] s;
public NumArray(int[] nums) {
s = new int[nums.length + 1];
for (int i = 0; i < nums.length; i++) {
s[i + 1] = s[i] + nums[i];
}
}
public int sumRange(int left, int right) {
return s[right + 1] - s[left];
}
}
/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* int param_1 = obj.sumRange(left,right);
*/
性能:
- 时间复杂度:初始化 O(n),其中 n 为 nums 的长度。sumRange O(1)。
- 空间复杂度:O(n)。