个人感觉这一题对优化的思维模式锻炼很有帮助,从刷题到实战都有一定借鉴性,值得研究
暴力解法:每次调用sumRange就去遍历数组中i->j并计算总和,缺点在于每一次调用sumRange都要遍历i->,多次调用时效率低。
优化思路(渐进式):1、初始化时先求出所有sumRange的和(每次调用sumRange就只要O(1)时间复杂度,但求出所有sumRange消耗较大),所以此方法有待优化。2、先求出所有前缀和,sumRange的结果只要用前缀和计算一次得出,求前缀和的消耗较小,且sumRange也能做到O(1)时间复杂度,求前缀和不要用双层for循环,用sum累加就可以做到O(n)的时间复杂度(这题优化的主要目的还是解决多次调用重复遍历i->j效率低的问题),此法甚妙
代码如下:
/**
* @param {number[]} nums
*/
var NumArray = function(nums) {
//初始化处理数组,在这里计算出所有前缀和
// 初始化数组长度为nums.length+1是为了不用处理索引为0的特殊情况,fill(0)是为了初始化数组每一项为Number类型,用于后面计算累加,
this.sum=new Array(nums.length+1).fill(0)
for(let i=0;i<nums.length+1;i++){
this.sum[i+1]=this.sum[i]+nums[i]
}
};
/**
* @param {number} left
* @param {number} right
* @return {number}
*/
NumArray.prototype.sumRange = function(left, right) {
// 因为求的是包含i,j两点的和,所以left不需要加一
return this.sum[right+1]-this.sum[left]
};
/**
* Your NumArray object will be instantiated and called as such:
* var obj = new NumArray(nums)
* var param_1 = obj.sumRange(left,right)
*/