算法笔记-力扣303. 区域和检索 - 数组不可变(一维前缀和)

前言

提示:这里可以添加本文要记录的大概内容:记录一下算法学习过程


提示:以下是本篇文章正文内容,下面案例可供参考

一、一维数组中的前缀和前缀和

前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。

二、题目

在这里插入图片描述

三、解答过程

题目要求你实现这样一个类:

class NumArray {
public:
    NumArray(vector<int>& nums) {}
    
    /* 查询闭区间 [left, right] 的累加和 */
    int sumRange(int left, int right) {}
};

sumRange 函数需要计算并返回一个索引区间之内的元素和,没学过前缀和的人可能写出如下代码:

class NumArray {
    
private:
    vector<int> nums;

public:
    NumArray(vector<int>& nums) {
        this->nums = nums;
    }
    
    int sumRange(int left, int right) {
        int res = 0;
        for (int i = left; i <= right; i++) {
            res += nums[i];
        }
        return res;
    }
};

这样,可以达到效果,但是效率很差,因为 sumRange 方法会被频繁调用,而它的时间复杂度是 O(N),其中 N 代表 nums 数组的长度。
最优解法是使用前缀和技巧,将 sumRange 函数的时间复杂度降为 O(1),也就是不要在 sumRange 里面用 for 循环。
代码实现:

class NumArray {
    private:
        // 前缀和数组
        vector<int> preSum;
    
    public:
        /* 输入一个数组,构造前缀和 */
        NumArray(vector<int>& nums) {
            // preSum[0] = 0,便于计算累加和
            preSum.resize(nums.size() + 1);
            // 计算 nums 的累加和
            for (int i = 1; i < preSum.size(); i++) {
                preSum[i] = preSum[i - 1] + nums[i - 1];
            }
        }
        
        /* 查询闭区间 [left, right] 的累加和 */
        int sumRange(int left, int right) {
            return preSum[right + 1] - preSum[left];//这里其实可以观察nums的累加和部分代码,其中 preSum[i] = preSum[i - 1] + nums[i - 1];简单的代数运算即可得出nums[i]=preSum[i + 1] - preSum[i]
        }
};

也就是new一个新的数组preSum出来,preSum[i]记录了nums[0,…i-1]的累加和,然后在给定的区间[left,right]中计算nums的和就可以通过preSum[right+1]-presum[left]
在这里插入图片描述
如果想要求索引区间[1,4]的累加和,就可以用preSum[5]-preSum[1]

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值