LeetCode*303. Range Sum Query - Immutable

LeetCode题目链接

题目:

Given an integer array nums, find the sum of the elements between indices i and j (ij), inclusive.

Example:

Given nums = [-2, 0, 3, -5, 2, -1]

sumRange(0, 2) -> 1
sumRange(2, 5) -> -1
sumRange(0, 5) -> -3

Note:
You may assume that the array does not change.
There are many calls to sumRange function.

解析:

这一题是求指定区间数组元素的和。并且要求不能改变原数组。这个方法会经常被调用。

由于经常被调用,如果按常规方法,开销会比较大,每次都要遍历并求和。已知数组不会改变,我们可以考虑能不能先计算一部分,节约后面调用的开销。
重新定义一个数组,这个数组保存从第一个元素到当前元素的累计值。现在想想,再求一个区间,只需要求两个值的差即可。

原数组:[1,2,1,9,5]
保存的数组:[0,1,3,4,13,18]
sumRange(2,4) = 18 - 3 = 15

Q:为什么第一个元素要置0?

有时候在思考一个问题时,可以反着思考,比如:如果不置0会怎么样?
那么就需要判断边界条件,首先是代码不够清晰,分支多;其次,性能也有影响。而加一个0可以将问题表现统一。 这里有兴趣的可以去看看linus 用双重指针操作链表的例子。链接

我觉得这题体现出把计算提前的思想,比如模板元编程,可以在编译期间计算出结果,而不用在运行时计算,运行次数越多,越体现优势。

答案:

class NumArray {
private:
    vector sumArray = {0};
    
public:
    NumArray(vector nums) {
        int sum = 0;
        for (int n : nums) {
            sum += n;
            sumArray.push_back(sum);
        }
    }
    
    int sumRange(int i, int j) {
        return sumArray[j + 1] - sumArray[i];
    }
};

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * int param_1 = obj.sumRange(i,j);
 */

你可能感兴趣的:(LeetCode*303. Range Sum Query - Immutable)