通用算法 - [数组算法] -数组的前缀和

108 阅读1分钟

1、前缀和介绍

对于一个数组AA,我们新建一个长度相等的数组BB,新数组中的每一项B[i]B[i]表示的是数组AA的前ii项和,即 前缀和BB中的每一项B[i]B[i]保存A[0,1,...,i]A[0,1,...,i]的和;

类似的概念还有: 后缀和BB中的每一项B[i]B[i]保存A[i,i+1,...,n1]A[i,i+1,...,n-1]的和; 前缀积: BB中的每一项B[i]B[i]保存A[0,1,...,i]A[0,1,...,i]的积; 后缀积: BB中的每一项B[i]B[i]保存A[i,i+1,...n1]A[i,i+1,...n-1]的积;

2、前缀和性质

(1)B[i]=A[i]+(i>1?B[i1]:0)B[i] =A[i] + (i > 1 ? B[i-1] : 0 ); (2)A[i]+A[i+1]+...+A[j]=B[j]B[i]A[i]+A[i+1]+...+A[j] = B[j] - B[i];

3、前缀和应用

(1) 数组分成差值最小的两部分 寻找一个位置pp,把数组numsnums从位置pp分开,使得nums[0]+nums[1]+...+nums[p]nums[0]+nums[1]+...+nums[p]nums[p+1]+nums[p+2]+...+nums[n1]nums[p+1] + nums[p+2]+...+nums[n-1]之差的绝对值最小。 分析:这道题相当于求位置pp,使得位置pp的前缀和与整个数组和-位置pp的前缀和的差的绝对值最小,即: minabs{sum[p](sum[n]sum[p]}=minabs{2sum[p]sum[n]}minabs\{ sum[p] - (sum[n] - sum[p] \} = minabs \{ 2*sum[p] - sum[n] \}

(2)和为0的子数组 在数组nums中找到所有和为0的子数组,返回这些子数组的起始和终止下标。 分析:若nums[i]+nums[i+1]+...+nums[j]=0nums[i] + nums[i+1] + ... + nums[j]=0,则有nums[0]+nums[1]+...+nums[j]=nums[0]+nums[1]+...+nums[i1]nums[0] + nums[1] + ... + nums[j] = nums[0] + nums[1] +... +nums[i-1],即nums[i1]=nums[j]nums[i-1]=nums[j],根据这一性质,我们可以知道和为00的子数组包含两种情况: a、位置ii的前缀和为00,子数组的起始位置和终止位置分别为00ii; b、位置ii的前缀和和位置jj的前缀和相等,子数组的起始位置和终止位置分别为i+1i+1jj

(3)最接近0的子数组和 找到和最接近0的子数组。 分析:对前缀和数组进行排序,然后看相邻排序后数组的相邻两个值sum[i]sum[i]sum[j]sum[j]是否接近,若接近,则子数组nums[i+1,...,j]nums[i+1,...,j]的和接近0.