通过前缀和数组保存前 n 位的和
构建前缀和数组的代码如下:
int[] presum=new int[nums.length];
presum[0]=nums[0];
for (int i = 1; i < nums.length; i++)
{
presum[i] = nums[i] + presum[i-1];
}
力扣1991 寻找数组的中间位置
暴力法:每个位置去计算它的左边和右边的所有元素相加之和
class Solution
{
public int pivotIndex(int[] nums)
{
for(int temp=0;temp<nums.length;temp++)
{
if(help(temp,nums)==true) return temp;
}
return -1;
}
public boolean help(int now,int[] nums)
{
int left=0,right=0;
for(int i=0;i<now;i++)
{
left=left+nums[i];
}
for(int j=now+1;j<nums.length;j++)
{
right=right+nums[j];
}
boolean result=(left==right?true:false);
return result;
}
}
前缀和的方法:
class Solution
{
public int findMiddleIndex(int[] nums)
{
int sum=0;
for(int num:nums)
{
sum=sum+num;
}
int preSum=0;//定义前缀和
for(int i=0;i<nums.length;i++)
{
int postSum=sum-preSum-nums[i];//求出nums[i]右边所有元素的和
if(preSum==postSum) return i;
//更新前缀和
preSum=preSum+nums[i];
}
return -1;
}
}
力扣303 计算区间的和
class NumArray
{
//定义一个数组,这个数组是前缀和数组,也就是说presum[i]表示前i个数的和
int[] presum;
public NumArray(int[] nums)
{
presum=new int[nums.length];
//初始化
presum[0]=nums[0];
for(int i=0;i<nums.length-1;i++)
{
presum[i+1]=presum[i]+nums[i+1];
}
}
public int sumRange(int left, int right)
{
if(left==0)
{
return presum[right];
}
return presum[right]-presum[left-1];
}
}
力扣560 和为k的子数组
暴力法也能过:
class Solution
{
public int subarraySum(int[] nums, int k)
{
int len = nums.length;
int sum = 0;
int count = 0;
//双重循环
for (int i = 0; i < len; ++i)
{
sum=0;
for (int j = i; j < len; ++j)
{
sum += nums[j];
//发现符合条件的区间
if (sum == k) {
count++;
}
}
}
return count;
}
}
力扣1480 一维数组的动态和
其实就是求前缀和数组
class Solution
{
public int[] runningSum(int[] nums)
{
int[] result=new int[nums.length];
int sum=0;
for(int i=0;i<nums.length;i++)
{
sum=sum+nums[i];
result[i]=sum;
}
return result;
}
}
还有类似前缀和的,前缀乘积
力扣238 除自身以外数组的乘积(注意这道题目不能使用除法)
求出前缀乘积和后缀乘积,然后相乘起来
class Solution
{
public int[] productExceptSelf(int[] nums)
{
int[] result1=new int[nums.length];
int[] result2=new int[nums.length];
int k=1;
//result1数组里此时每个位置的元素是当前元素左边的所有元素的乘积
for(int i=0;i<nums.length;i++)
{
result1[i]=k;
k=k*nums[i];
}
k=1;
//result2数组里此时每个位置的元素是当前元素右边的所有元素的乘积
for(int j=nums.length-1;j>=0;j--)
{
result2[j]=k;
k=k*nums[j];
}
for(int i=0;i<nums.length;i++)
{
result2[i]=result1[i]*result2[i];
}
return result2;
}
}