1658. 将 x 减到 0 的最小操作数
Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述
给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。 示例 1:
输入: nums = [1,1,4,2,3], x = 5
输出: 2
解释: 最佳解决方案是移除后两个元素,将 x 减到 0 。
具体题目链接: 题目链接
思路:
思路:滑动窗口思路
窗口扩展时寻找可行解,窗口收缩时优化可行解
当滑动窗口可以定长时,一直维护k个长度的滑动窗口即可
当滑动窗口需要不定长时,需要通过特定条件(比如滑动窗口的总和)来判断left和right指针 到底是移动哪个
分析:
将随机删除两端元素变成寻找连续子序列
你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值,言外之意(找到一个和为 sum - x 的最长连续子数组)
sum:nums总和
x:需要减去两端的值
window:滑动窗口
windowsum:滑动窗口的总和
right:滑动窗口右端点
left:滑动窗口左端点
count = sum - x;
if(windowsize>0)说明要收缩,left++;
<0;说明不存在,返回-1;
这题都是正数,如果有负数,参考560,使用前缀和+hash
代码:
var minOperations = function(nums, x) {
let n = nums.length;
let res = -1;//保存答案的最值
//sum总和
let sum = 0;
for(let i=0;i<n;i++) {
sum+=nums[i];
}
let count = sum - x;//分情况判断>0 =0 <0的情况
if(count < 0)return -1;
let windowsum = 0;
let right =0;
let left = 0;
while(right < n) {
windowsum += nums[right];
//当滑动窗口里面总和 大于 count值的时候, 说明要减少滑动窗口
while(windowsum > count) {
windowsum -= nums[left];//值也要跟着动起来
left++;
}
if(windowsum == count) { //相等时,说明找到了一组解,保存最大的题解
res = Math.max(res, right-left+1);
}
right++;
}
if(res == -1)return -1;
return n - res;
};
总结:
这是算法系列文章「滑动窗口」的相关题解
类型滑动窗口类型题目,解题方法窗口扩展时寻找可行解,窗口收缩时优化可行解