LeetCode 1658. 将x减到0的最小操作数
题目:
给你一个整数数组 nums
和一个整数 x
。每一次操作时,你应当移除数组 nums
最左边或最右边的元素,然后从 x
中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x
恰好 减到 0
,返回 最小操作数 ;否则,返回 -1
。
思路:逆向思维 + 滑动窗口
移除的是 nums 最左边或最右边的元素,那么剩下的元素是什么?是 nums 的连续子数组。
移除的元素和 x + 剩余的元素和 = nums 的所有元素之和 s。所以剩余的元素和 = s−x。
问题变成:从 nums 中找最长的子数组(这样移除的数尽量少),满足子数组的元素和恰好等于 s−x。 最后答案为 nums 的长度减去最长子数组的长度。
注意:子数组的长度可以是 0,所以下面代码初始化 ans=−1。如果初始化 ans=0,就无法区分是否真的存在符合要求的子数组。
代码:
class Solution {public int minOperations(int[] nums, int x) {int n = nums.length;int left = 0;int ans = -1;int sum = 0;for (int num : nums) {sum += num;}if (sum < x) {return -1;}int add = 0;for (int right = 0; right < n; right++) {add += nums[right];while (add > sum - x) {add -= nums[left++];}if (add == sum - x) {ans = Math.max(ans, right - left + 1);}}return ans < 0 ? -1 : n - ans;}
}
性能: