Every day a leetcode
题目来源:303. 区域和检索 - 数组不可变
解法1:暴力
代码:
class NumArray
{
public:
vector<int> v;
NumArray(vector<int> &nums)
{
v = nums;
}
int sumRange(int left, int right)
{
int sum = 0;
for (int i = left; i <= right; i++)
sum += v[i];
return sum;
}
};
结果:
居然能AC…
复杂度分析:
时间复杂度:O(n),其中n是数组nums的长度。复制数组的时间复杂度为O(n),sumRange的时间复杂度也为O(n)。
空间复杂度:O(n),其中n是数组nums的长度。
解法2:前缀和
在初始化时,使用sums数组计算nums数组的前缀和。
设nums数组的长度为n,创建长度为n+1的sums数组。
对于0≤i<n,都有sums[i+1]=sums[i]+nums[i],则当0<i≤n时,sums[i]表示nums数组从下标 0 到下标 i−1 的前缀和。
此时有:
sumRange(i, j)=sums[j+1]−sums[i]
每次调用sumRange的时间复杂度都是O(1)。
代码:
/*
* @lc app=leetcode.cn id=303 lang=cpp
*
* [303] 区域和检索 - 数组不可变
*/
// @lc code=start
class NumArray
{
public:
vector<int> sums;
NumArray(vector<int> &nums)
{
int n = nums.size();
sums.resize(n + 1);
for (int i = 0; i < n; i++)
{
sums[i + 1] = sums[i] + nums[i];
}
}
int sumRange(int left, int right)
{
return sums[right + 1] - sums[left];
}
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* int param_1 = obj->sumRange(left,right);
*/
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(n),其中n是数组nums的长度。计算前缀和数组的时间复杂度为O(n),sumRange的时间复杂度为O(1)。
空间复杂度:O(n),其中n是数组nums的长度。需要创建一个长度为 n+1 的前缀和数组。