1、前缀和介绍
对于一个数组A,我们新建一个长度相等的数组B,新数组中的每一项B[i]表示的是数组A的前i项和,即
前缀和:B中的每一项B[i]保存A[0,1,...,i]的和;
类似的概念还有:
后缀和:B中的每一项B[i]保存A[i,i+1,...,n−1]的和;
前缀积: B中的每一项B[i]保存A[0,1,...,i]的积;
后缀积: B中的每一项B[i]保存A[i,i+1,...n−1]的积;
2、前缀和性质
(1)B[i]=A[i]+(i>1?B[i−1]:0);
(2)A[i]+A[i+1]+...+A[j]=B[j]−B[i];
3、前缀和应用
(1) 数组分成差值最小的两部分
寻找一个位置p,把数组nums从位置p分开,使得nums[0]+nums[1]+...+nums[p]与nums[p+1]+nums[p+2]+...+nums[n−1]之差的绝对值最小。
分析:这道题相当于求位置p,使得位置p的前缀和与整个数组和-位置p的前缀和的差的绝对值最小,即:
minabs{sum[p]−(sum[n]−sum[p]}=minabs{2∗sum[p]−sum[n]}
(2)和为0的子数组
在数组nums中找到所有和为0的子数组,返回这些子数组的起始和终止下标。
分析:若nums[i]+nums[i+1]+...+nums[j]=0,则有nums[0]+nums[1]+...+nums[j]=nums[0]+nums[1]+...+nums[i−1],即nums[i−1]=nums[j],根据这一性质,我们可以知道和为0的子数组包含两种情况:
a、位置i的前缀和为0,子数组的起始位置和终止位置分别为0和i;
b、位置i的前缀和和位置j的前缀和相等,子数组的起始位置和终止位置分别为i+1和j。
(3)最接近0的子数组和
找到和最接近0的子数组。
分析:对前缀和数组进行排序,然后看相邻排序后数组的相邻两个值sum[i]和sum[j]是否接近,若接近,则子数组nums[i+1,...,j]的和接近0.