滑动窗口是一种基于双指针的思想,两个指针之间的元素之间形成一个“窗口”。
初始时,left,right = 0;right指针右滑,当之间的元素超过条件时,left指针右滑。直到窗口元素满足条件,或right超出边界。
时间复杂度是O(n)的。
// 逆向思维
// class Solution {
// public int minOperations(int[] nums, int x) {
// int target = -x;
// for(int num : nums){
// target += num;
// }
// if(target < 0) return -1;
// int ans = -1,left = 0,sum = 0;
// for(int right = 0; right < nums.length; right++){
// sum += nums[right];
// while(sum > target) sum -= nums[left++];
// if(target == sum) ans = Math.max(ans, right - left + 1);
// }
// return ans < 0 ? -1 : nums.length - ans;
// }
// }
// 正向求解
class Solution {
public int minOperations(int[] nums, int x) {
int n = nums.length;
int sum = Arrays.stream(nums).sum();
if (sum < x) {
return -1;
}
//right是后缀边界,left是前缀边界。初始时前缀为0,整个数组为后缀。
int right = 0;
int lsum = 0, rsum = sum;
int ans = n + 1;
for (int left = -1; left < n; ++left) {
if (left != -1) {
lsum += nums[left];
}
while (right < n && lsum + rsum > x) {
rsum -= nums[right];
++right;
}
if (lsum + rsum == x) {
ans = Math.min(ans, (left + 1) + (n - right));
}
}
return ans > n ? -1 : ans;
}
}