前言
前缀和是一种非常简单的算法,但是我们也要熟练掌握,前缀和算法是一种用于快速求解一系列数据中某个区间内所有数值和的技巧。它通过一次性计算出从数组开始到每个位置的累积和,从而使得任何区间的和都可以通过简单的减法操作在常数时间内得到。
一、前缀和算法
1.1、前缀和算法的基本思想
在前缀和算法中,我们首先计算一个前缀和数组S,其中S[i]表示原数组a中从a[1]到a[i]的和。这样,如果我们想要得到从l到r的区间和,只需要计算S[r] - S[l-1]即可。这种方法的优势在于,无论区间多大,求区间和的时间复杂度都是O(1)。
1.2、前缀和数组的计算
前缀和数组可以通过一次遍历原数组来计算得到。具体的计算方法如下:
假设原数组为a,n为数组长度
# 创建前缀和数组,长度为n,S[0]初始化a[0]
for(int i=1;i<n;i++)
S[i] = S[i - 1] + a[i - 1]
1.3、前缀和的应用
前缀和算法不仅可以用于一维数组,还可以扩展到二维数组或矩阵中。在二维数组中,我们可以计算出一个二维前缀和矩阵,用于快速求解子矩阵的元素和。
二、经典例题
2.1、一维数组的动态和
(帅哥们这个蓝色字体可以点进去看原题)
代码题解
class Solution {
public:
vector<int> runningSum(vector<int>& nums) {
int n=nums.size();
vector<int>runningSum={nums[0]};//给前缀和数组初始化第一个值为nums[0]
for(int i=1;i<n;i++){
int x=runningSum.back()+nums[i];
runningSum.push_back(x);
}
return runningSum;
}
};
2.2、找数组的中间位置
(帅哥们这个蓝色字体可以点进去看原题)
解题思路
遍历整个数组,用前缀和数组的最后一个元素(也就是数组所有元素之和)减去遍历到的那个下标,然后判断这个小标前一个位置的前缀和数组元素(也就是这个下标以前所有的元素之和),特别注意如果下标为0,那么前半段的和为0。
代码题解
class Solution {
public:
int findMiddleIndex(vector<int>& nums) {
int sum[210];
int n=nums.size();
sum[0]=nums[0];
for(int i=1;i<n;i++){
sum[i]=sum[i-1]+nums[i];
}//求出前缀和数组
for(int i=0;i<n;i++){
int a=0,b=0;//a代表前半段和,b代表后半段和
int middleIndex=i;//标记结果下标
if(middleIndex)a=sum[middleIndex-1];//判断下标是否为0
b=sum[n-1]-sum[middleIndex];
if(a==b)return middleIndex;
}
return -1;
}
};
2.3、寻找数组中心下标
(帅哥们这个蓝色字体可以点进去看原题)
解题思路
这题和上题思路一样,不会的可以重开了。
代码题解
class Solution {
public:
int pivotIndex(vector<int>& nums) {
int n=nums.size();
for(int i=1;i<n;i++)
nums[i]=nums[i-1]+nums[i];
for(int i=0;i<n;i++){
int a=0,b=0;
if(i)a=nums[i-1];
b=nums[n-1]-nums[i];
if(a==b)return i;
}
return -1;
}
};