算法基础之前缀和

       如果有一个数组arr = [1, 5, 8, 2, 13, 6],我们对其进行T次询问,每次询问[r, l]r, l均为数组arr的下标,在此数组中符合(0 <= r <= 5)),假设对其询问3次(T = 3),第一次询问[13],第二次询问[24],第三次询问[25],我们不难算出来,第一次询问的结果是5 + 8 + 2 = 15,第二次询问的结果是8 + 2 + 13 = 23,第三次询问的结果是8 + 2 + 13 + 6 = 29,当然,如果数组长度比较短的话当然可以这么做,如果当数组的长度比较长时,询问T次最坏情况下无非就是每次都询问[0, arr.length()]的区间和,其时间复杂度为O(N * T),这样的时间代价无非时非常高的,这时候我们不妨引入前缀和的概念:

      我们不妨维护一个数组nums,使得numsi > 0 时,nums[i] = nums[i - 1] + arr[i], i = 0 时,nums[0] = arr[0]; 此时我们再对arr数组进行处理,nums = [1, 6, 14, 16, 29, 35],此时的nums[i]就是arr[0, i]的区间和, 好的,直接上公式,l(区间的左边界) = 0时,arr[l, r] = nums[r] l > 0时,arr[l, r] = nums[r] – nums[l - 1],此时我们不妨将上面询问三次将公式里带入求证,当询问[1, 3]时,arr[1, 3] = nums[3] – nums[0] = 16 – 1 = 15 当询问[2, 4]时,arr[2, 4] = nums[4] – nums[1] = 29 – 6 = 23,当询问[2, 5]时,arr[2, 5] = nums[5] = nums[1] = 35 – 6 = 29。看样子完全正确,这就是利用了前缀和,其时间复杂度为O(1),能极大的缩短我们的询问时间,提高我们的效率。

下面是代码块:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i, t;
    vector<int>arr = {1, 5, 8, 2, 13, 6};
    vector<int>nums(6, 0);
    //建立数组nums
    for (i = 0; i < 6; i++) {
        if (i == 0)
            nums[i] = arr[i];
        else
            nums[i] = nums[i - 1] + arr[i];
    }
    cin >> t;
    //对其进行t次询问
    while (t--) {
        int l, r;
        cin >> l >> r;
        cout << "区间[" << l <<"," << r << "]的前缀和为:";
        if (l > 0)
            cout << nums[r] - nums[l - 1] << endl;
        else
            cout << nums[r] << endl;
    }


    system("pause");
    return 0;
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值