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 is 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
Given an integer array nums
and an integer x
, you can remove elements from either the left or right end of the array and subtract their values from x
. The goal is to find the minimum number of operations needed to reduce x
to exactly 0. If it's impossible, return -1.
This approach leverages the observation that we're essentially looking for a subarray within nums
whose sum, when subtracted from the total sum of nums
, equals x
. Finding the longest such subarray minimizes the number of operations (elements removed from both ends).
Calculate Target Sum: Compute the target sum s = sum(nums) - x
. If s
is negative, it's impossible to reach 0, so we return -1.
Two Pointers: Use two pointers, i
(left) and j
(right), to maintain a sliding window. i
iterates through the array, adding each element to a running sum t
.
Window Adjustment: If t
exceeds s
, we shrink the window by incrementing j
and subtracting nums[j]
from t
. This ensures t
always remains less than or equal to s
.
Longest Subarray: When t
equals s
, we've found a subarray with the target sum. We update mx
(maximum length) with the current window size (i - j + 1
).
Result: The minimum number of operations is len(nums) - mx
. If mx
remains -1 (no subarray found), we return -1.
nums
. We traverse the array once.class Solution:
def minOperations(self, nums: List[int], x: int) -> int:
s = sum(nums) - x
if s < 0:
return -1
mx, t = -1, 0
j = 0
for i, v in enumerate(nums):
t += v
while j <= i and t > s:
t -= nums[j]
j += 1
if t == s:
mx = max(mx, i - j + 1)
return len(nums) - mx if mx != -1 else -1
class Solution {
public int minOperations(int[] nums, int x) {
int s = 0;
for (int num : nums) {
s += num;
}
s -= x;
if (s < 0) {
return -1;
}
int maxLen = -1;
int sum = 0;
int j = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
while (j <= i && sum > s) {
sum -= nums[j++];
}
if (sum == s) {
maxLen = Math.max(maxLen, i - j + 1);
}
}
return maxLen == -1 ? -1 : nums.length - maxLen;
}
}
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int s = accumulate(nums.begin(), nums.end(), 0) - x;
if (s < 0) return -1;
int mx = -1, t = 0;
int j = 0;
for (int i = 0; i < nums.size(); ++i) {
t += nums[i];
while (j <= i && t > s) {
t -= nums[j++];
}
if (t == s) {
mx = max(mx, i - j + 1);
}
}
return mx == -1 ? -1 : nums.size() - mx;
}
};
(Similar implementations can be easily adapted for other languages like JavaScript, Go, etc.)
This two-pointer approach provides an efficient solution with optimal time complexity, making it a preferred method for solving this problem. The other approach using Hash Tables and Prefix Sums, while functionally correct, has a slightly higher space complexity due to the hash table.