p87 不可变数组的区间和查询(leetcode 303)

一:解题思路

这道题目看起来比较简单,只需要将数组对应的从i到j的下标中的元素累加就行。但题目说了,会多次调用这个函数。是不是有更高效的做这个题目的方法呢?当然有,我们可以用一个简单的公式来计算一下。我们定义S(i)为从0到i-1的和,S(j)定义为从0到j-1的和,那么f(i,j)=S(j+1)-s(i)。我们提前把各个区段的和先计算好,然后计算时只需要从中取出即可。Time:O(n),Sapce:O(n)

二:完整代码示例 (C++版和Java版)

如果题目没有提到多次调用这个函数,我们可以直接用下面的解法就行。

class NumArray 
{
private:
    vector<int> arr;
public:
    NumArray(vector<int>& nums) 
    {
        arr = nums;
    }

    int sumRange(int i, int j) 
    {
        int sum = 0;
        for (int k = i; k <= j; k++)
        {
            sum += (arr[k]);
        }

        return sum;
    }
};

C++:

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

    int sumRange(int i, int j) 
    {
        return prefixSum[j + 1] - prefixSum[i];
    }
};

 

Java:

class NumArray {
        private final int[] prefixSum;

        public NumArray(int[] nums)
        {
               prefixSum=new int[nums.length+1];
               for(int i=1;i<prefixSum.length;i++)
                   prefixSum[i]=prefixSum[i-1]+nums[i-1];
        }

        public int sumRange(int i, int j)
        {
               return prefixSum[j+1]-prefixSum[i];
        }
    }

 

上一篇:程序员面试金典 - 面试题 17.24. 最大子矩阵(转成一维最大子序和 DP)


下一篇:StringBuilder 清除性能对比