持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
看一百遍美女,美女也不一定是你的。但你刷一百遍算法,知识就是你的了~~
谁能九层台,不用累土起!
题目
给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。
示例 1:
输入: nums = [1,1,4,2,3], x = 5
输出: 2
解释: 最佳解决方案是移除后两个元素,将 x 减到 0 。
示例 2:
输入: nums = [5,6,7,8,9], x = 4
输出: -1
示例 3:
输入: nums = [3,2,20,1,1,3], x = 10
输出: 5
解释: 最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。
提示:
1 <= nums.length <= 1051 <= nums[i] <= 1041 <= x <= 109
解题思路
- 我们用滑动窗口的思路来解决本题
- 用数组全部元素的和减去窗口内元素的和如果正好等于
x,则表明满足题意 - 我们在维护这个窗口的长度最大的时候,那么移除的元素就越少,也就是对应的操作数最少
解题代码
var minOperations = function(nums, x) {
const len = nums.length
const total = nums.reduce((prev,cur)=>prev+cur) // 所有元素的和
if(total<x) return -1 //边界处理,如果总和都不达 x,直接结束
let res = Infinity // 记录操作次数
let sum = 0 // 用于记录窗口内元素的和
let left =0
let right = 0
while(right<len){
sum += nums[right]
while(total-sum<x){ // 窗口外元素的和小于x 需要收紧窗口
sum -= nums[left]
left++
}
if(total-sum==x){ // 满足要求时,res取操作次数更少的
res =Math.min(res,len-(right-left+1))
}
right++
}
return res ==Infinity?-1:res
};
生活不是选择是热爱 我去寻我的心之所向素履以往 山高路远看世界也找自己.
如有任何问题或建议,欢迎留言讨论!