前缀和
前言
空间复杂度对代码运行的时间有着很重要的
作用,在代码中适当的用前缀和来进行维护
可以很好地节约时间复杂度。
一、前缀和是什么?
前缀和,通俗的说:对存有一些数字的某个数组而言,前缀就是指的其数组的前k项相加的值,因此对应的前缀和就是数组前k项的和。对一个数组,问[L,R]的区间和(从第L项到第R项的值相加的和),就可以利用前缀和进行求解。
二、一维前缀和讲解
一维前缀和大概就是:有一个由N个数字组成的数组arr[ ],对其进行q次的询问求[L,R]的区间和。
举例说明
数组arr[ ]是由1,3,7,5,2按顺序组成,对其进行3次询问分别是
[2,4],[0,3],[3,4]的区间和。
一般解法:
第一次询问: 区间和[2,4]=7+2+5=14;
第二次询问: 区间和[0,3]=1+3+7+5=16;
第三次询问: 区间和[3,4]=5+2=7;
如果每次询问都要先读入数组一个一个相加太过麻烦,此时我们可以引入前缀和数组:
sum[i]=sum[i-1]+arr[i] i>0
sum[0]=arr[0] i=0
解释一下sum[i]==arr[0]+arr[i]+…+arr[i],即sum[i]就是arr数组从第0项到第i项的和。
arr 1 3 7 5 2
sum 1 4 11 16 18
由sum数组求解该题就简单多了
第一次询问:区间和[2,4]=sum[4]-sum[1]=18-4=14=7+5+2
原因:将arr数组分为两块,一块是由第0项和第一项组成的非所求部分,
另一块是从第2项到第4项组成的所求部分,二者共同组成了整体sum[4],
由第0项和第一项组成的非所求部分可以看成sum[1],
所求部分=整体sum[4]-非所求sum[1]
非所求 | 所求 |
---|---|
1 3 | 7 5 2 |
扩大一下范围,把眼界打开,
设区间和[L,R]用sum[L,R]表示
根据第一次求解过程,我们就可以推出
sum[L,R]=sum[R]-sum[L-1] L>0
sum[L.R]=sum[R] L=0
代码如下(示例):
#include<iostream>
using namespace std;
const int n=5;
int sum[n];
int get_sum(int L,int R)
{
if(L!=0)
return sum[R]-sum[L-1];
else
return sum[R];
}
int main()
{
int arr[n]={1,3,7,5,2};
sum[0]=arr[0];
for(int i=1;i<n;i++)
sum[i]=sum[i-1]+arr[i];
cout<<get_sum(2,4)<<endl;
cout<<get_sum(0,3)<<endl;
cout<<get_sum(3,4)<<endl;
return 0;
}
代码献上,有助于理解
总结
本章一维前缀和简简单单,是我通过b站学的,算是自己的笔记吧,也分享给大家希望大家也能学会。