欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Leetcode-303.区域和检索-数组不可变

程序员文章站 2022-04-02 10:17:33
题目:给定一个整数数组 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”, “sumRang...

题目:

给定一个整数数组 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