[LeetCode] 1658. Minimum Operations to Reduce X to Zero
You are given an integer array nums
and an integer x
. In one operation, you can either remove the leftmost or the rightmost element from the array nums
and subtract its value from x
. Note that this modifies the array for future operations.
Return the minimum number of operations to reduce x
to exactly 0
if it's possible, otherwise, return -1
.
Example 1:
Input: nums = [1,1,4,2,3], x = 5 Output: 2 Explanation: The optimal solution is to remove the last two elements to reduce x to zero.
Example 2:
Input: nums = [5,6,7,8,9], x = 4 Output: -1
Example 3:
Input: nums = [3,2,20,1,1,3], x = 10 Output: 5 Explanation: The optimal solution is to remove the last three elements and the first two elements (5 operations in total) to reduce x to zero.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 104
1 <= x <= 109
将 x 减到 0 的最小操作数。
给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-operations-to-reduce-x-to-zero
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路是前缀和/滑动窗口,我参考了这个帖子。首先我们对目标值 X 翻译一下,因为题目问的其实是数组中间的某个子数组,满足其数组和 = 数组全部数字的和 - 两边某一些数字,所以目标值 X = 数组所有元素的和 totalSum - 左边一些元素的和 left - 右边一些元素的和 right。参见如下这个截图。
所以这道题可以转化为寻找一个数组和为 totalSum - x 的子数组,并且试图让这个子数组的长度尽可能最长,从而我们就得出最少需要移除几个元素了。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int minOperations(int[] nums, int x) { 3 int target = 0; 4 int len = nums.length; 5 for (int num : nums) { 6 target += num; 7 } 8 // corner case 9 // 如果整个数组的和 == X,说明需要移除所有元素 10 if (target == x) { 11 return len; 12 } 13 14 // normal case 15 // target = totalSum - x 16 target -= x; 17 HashMap<Integer, Integer> map = new HashMap<>(); 18 map.put(0, -1); 19 int res = Integer.MIN_VALUE; 20 // 前缀和 21 int sum = 0; 22 for (int i = 0; i < len; i++) { 23 sum += nums[i]; 24 // 找有没有前缀和 - 蓝色部分 25 if (map.containsKey(sum - target)) { 26 res = Math.max(res, i - map.get(sum - target)); 27 } 28 map.put(sum, i); 29 } 30 return res == Integer.MIN_VALUE ? -1 : len - res; 31 } 32 }