目录
前缀和的作用:
能求出一段区间内的数的和(在O(1)的时间内)
如果构造的sum是(n大小且sum[0]=nums[i]) ans=sum[right]-sum[left-1]
如果构造的sum是(n大小且sum[1]=nums[0]) ans=sum[right+1]-sum[left]
构造前缀和的模板:
n+1的模板:
class Solution {
public:
vector<int> runningSum(vector<int>& nums) {
int n=nums.size();
vector<int> ans(n+1,0);
for(int i=0;i<n;i++)
{
ans[i+1]=ans[i]+nums[i];
}
return ans;
}
};
n的模板:
class Solution {
public:
vector<int> runningSum(vector<int>& nums) {
int n=nums.size();
vector<int> ans(n+1,0);
for(int i=0;i<n;i++)
{
ans[i+1]=ans[i]+nums[i];
}
return ans;
}
};
1:寻找数组的中心下标(简单)
思路解析:
中心下标:这个位置的左边的数之和==这个位置的右边的数之和
那么数组的总和为sum,就有组合公式leftsum+nums[i]+rightsum=sum
移项则有:leftsum=sum-rightsum-nums[i]
即我们只需求出sum,再遍历左侧前缀和即可
class Solution {
public:
int pivotIndex(vector<int>& nums) {
int sum = 0;
for (int num : nums) sum += num; // 求和
int leftSum = 0; // 中心索引左半和
int rightSum = 0; // 中心索引右半和
for (int i = 0; i < nums.size(); i++) {
leftSum += nums[i];
rightSum = sum - leftSum + nums[i];
if (leftSum == rightSum) return i;
}
return -1;
}
};
2:逐步求和得到正数的最小值(简单)
思路解析:
利用前缀和求出这个原数组nums对应的前缀和数组ans,题目要求的题意即可转变为将前缀和数组的最小值至少加上x,使得数组的每个数都大于或等于1
构造好前缀和数组后,我们初始化min=INT_MAX,求最小值,共有两种情况
如果min的值出来后大于等于1,那么证明前缀和数组都是正数,所以无需加上数字
如果min的值出来后小于1,那么就根据样例进行调整即可
class Solution {
public:
int minStartValue(vector<int>& nums) {
int Min=INT_MAX;
int sum=0;
for(int num:nums)
{
sum+=num;
Min=min(Min,sum);
}
if(Min>=1) return 1;//证明数组中的数都是正数
else return abs(Min)+1;//数组中存在负数
}
};
3:找到最高海拔(简单)
思路解析:
根据原数组构造出前缀和数组,并求出前缀和数组的最大值即可
class Solution {
public:
int largestAltitude(vector<int>& gain) {
int n=gain.size();
vector<int> ans(n+1,0);
for(int i=0;i<n;i++) ans[i+1]=ans[i]+gain[i];
int MAX=INT_MIN;
for(int i=0;i<n+1;i++)
{
if(ans[i]>MAX)
{
MAX=ans[i];
}
}
return MAX;
}
};
4:所有奇数长度子数组的和(有点不简单)
思路解析:
有两条路的遍历方式:
(1)像解释一样,先遍历1个1组的,再遍历3个1组的,再遍历5个一组的…………
(2)先遍历以1为头的所有奇数数组,比如1本身和[1,4,2]和[1,4,2,5,3],再遍历以2为头的
这里选择第一种遍历方式
(1)构造前缀和
(2)步长限制(step)(当步长大于等于这个数组长度时,跳出)
(3)for循环用i遍历,把nums[i]作为每个的头,并以步长的单位进行求区间和
(4)更新步长:step+=2;
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int n=arr.size();
vector<int> ans(n+1,0);