1、题目描述
给你一个整数数组 nums
和一个整数 x
。每一次操作时,你应当移除数组 nums
最左边或最右边的元素,然后从 x
中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x
恰好 减到 0
,返回 最小操作数 ;否则,返回 -1
。
2、算法思路
我们可以通过问题转化,把问题转化成在nums的一段连续的区间中,target = sum - x,我们只需要在在nums中找到这个区间里面最大的元素的长度等于targer。
3、算法流程
3.1 求nums中的总数和 sum。如果sum<x,问题无解,返回-1,如果sum = x,返回nums.length。
3.2 设置左右指针,目的是通过滑动窗口来寻找nums中的值等于target
3.3 进窗口 每个rigth的元素进入窗口
判断 判断窗口中的值是否大于target
出窗口 如果大于,左指针出窗口
更新结果 如果窗口内元素的总值大于target,更新ret,通过比较
4、算法代码
class Solution {
public int minOperations(int[] nums, int x) {
int sum = 0;
for(int i : nums) sum += i; //计算sums中元素的总和
if(sum < x) return -1;//表示区间内的值加起来也达不到x
if(sum == x) return nums.length;
int targer = sum -x;//连续的区间需要计算达到的目标值
int ret = Integer.MIN_VALUE;//ret初始化,表示任意一个值都可以替换它
int temp = 0,n = nums.length;
for(int left =0,right = 0;right < n;right++){
temp += nums[right];//进窗口
while(temp > targer){ //判断
temp -= nums[left];//出窗口
left++;
}
if(temp == targer){//更新结果
ret = Math.max(ret,right - left+1);
}
}
if(ret == Integer.MIN_VALUE){
return -1;
}else{
return n -ret;
}
}
}