题目
题解
题目可以简化为:求最小操作数使得数组的 前缀+后缀=x,其中前缀或者后缀可以为空。
滑动窗口
用两个变量left和right记录前缀和后缀的边界,lsum为前缀和,rsum为后缀和。
初始状态left=-1,right=0,由于数组中都是正数,所以left右移的话,它们的和一定是单调递增的,因此需要根据 和的大小调整left和right的位置,分为以下三种情况:
- lsum+rsum==x,找到一组答案,操作次数为(left+1)+(n-right)
- lsum+rsum > x,right右移
- lsum+rsum < x,left右移
最终返回最小的操作次数即可
附:记一下整数数组求和代码Arrays.stream(nums).sum()
class Solution {
public int minOperations(int[] nums, int x) {
int n=nums.length,res=n+1;
int sum=Arrays.stream(nums).sum();
int right=0,lsum=0,rsum=sum;
for(int left=-1;left<n;left++){
//更新前缀
if(left!=-1){
lsum+=nums[left];
}
//和大于x,right后移,缩小后缀
while(right<n&&lsum+rsum>x){
rsum-=nums[right];
right++;
}
//满足条件,取最小操作数
if(lsum+rsum==x)
res=Math.min(res,left+1+n-right);
}
return res>n?-1:res;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)