题目:

给定一个整数数组 nums,求出数组从索引 i 到 j(i ≤ j)范围内元素的总和,包含 i、j 两点。

实现 NumArray 类:

NumArray(int[] nums) 使用数组 nums 初始化对象
int sumRange(int i, int j) 返回数组 nums 从索引 i 到 j(i ≤ j)范围内元素的总和,包含 i、j 两点(也就是 sum(nums[i], nums[i + 1], … , nums[j]))

示例:

输入:

[“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))

提示:

0 <= nums.length <= 104
-105 <= nums[i] <= 105
0 <= i <= j < nums.length
最多调用 104 次 sumRange 方法

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/range-sum-query-immutable
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

首先作为萌新,第一个想到的就是暴力解法,直接利用for循环将下标 i 到 j 的每一项全部加起来,但是时间复杂度每次都是O(n),反复调用花费的时间会特别多。

因此尝试在暴力解法的基础上进行优化,因为数组是固定不变的,如果说在创建类内部数组的时候进行前缀和计算,最后求 i 到 j 范围内元素的总和只需要利用对应前缀和求差进行运算就可以了。

原始数组

-2 0 3 -5 2 -1

前缀和数组(首位未添加0)

-2 -2 1 -4 -2 -3

不过因为求出数组从索引 i 到 j(i ≤ j)范围内元素的总和时是包含 i、j 两点,因此在这里需要考虑 i=0 的情况,可以使用 if 进行处理,不过事后看了题解,尝试在前缀和数组首添加一位0会更加方便求解。

前缀和数组

0 -2 -2 1 -4 -2 -3

这个时候会发现,求出数组从索引 i 到 j(i ≤ j)范围内元素的总和(包含 i、j 两点),只需要用 sums[j+1]-sums[i] 即可。

代码

class NumArray { 
private:
    vector<int> sums;
public:
    NumArray(vector<int>& nums) { 
        sums.push_back(0);
        for(int i=0;i<nums.size();i++){ 
            sums.push_back(sums[i]+nums[i]);
        }
    }
    
    int sumRange(int i, int j) { 
        return sums[j+1]-sums[i];
    }
};

本文地址:https://blog.csdn.net/veritas_5bor/article/details/114260369