题目描述
给你一个整数数组 nums
和一个整数 x
。每一次操作时,你应当移除数组 nums
最左边或最右边的元素,然后从 x
中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x
恰好 减到 0
,返回 最小操作数 ;否则,返回 -1
。
力扣:1658. 将 x 减到 0 的最小操作次数
输入:nums = [3,2,20,1,1,3], x = 10
输出:5
解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。
注意:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^4
1 <= x <= 10^9
题目分析
每次都从数组 开头
和 结尾
进行取数,而最终 x
变为 0
,即从开头和结尾取出来的数总和为 x
若每次都从数组的开头和结尾处取值,则 剩余未取的数在数组中是连续的 ,且其 总和为数组总和 sum - x
;而题目求的是从开头 和 结尾 拿的最少次数 , 等价于 求总长度 - 余下数的最大长度
。
class Solution {
public int minOperations(int[] nums, int x) {
int sum = 0;
for(int num : nums){
sum += num;
}
int target = sum - x;
if(target < 0) return -1; // 因为所有的数都是正数
int left = 0 , right = 0 , max_len = -1;
while (right < nums.length){
target -= nums[right++];//窗口右侧主动扩张
while (target < 0) target += nums[left++]; //窗口左侧适应性收缩
if(target == 0) max_len = Math.max( max_len , right -left);
}
return max_len == -1 ? -1 :nums.length -max_len;
}
}