这题一开始试图用贪心,我用两个指针分别指向头和尾,然后每次选较大的值,移动指针,直到和加起来=x,但是如果两个值相等,该如何移动?就不行了。DP也考虑过,时间复杂度较高。
然后换一种思路,在原数组两端找两个子数组和=x,等同于在原数组中间找一个连续的子数组和=原数组和-x。这样就可以用滑动窗口了,sum表示原数组总和,用midSum记录中间数组的和,每次循环先移动右边界,如果midSum>sum-x,且right>=left,则一直左移left;这里right>=lefth很重要,我一开始漏掉了right=left的情况,这时候left左移之后=right+1,midSum=0。每轮循环最后,如果left不再需要左移了,判断midSum==sum-x,相等则更新答案。我初始化ans为int最大值,每次更新保留最小值,如果最终ans没有被更新过,那么就是没找到,返回-1。
class Solution {
public int minOperations(int[] nums, int x) {
int ans = Integer.MAX_VALUE;
int sum = 0;
for (int n : nums) {
sum += n;
}
int midSum = 0;
for (int left = 0, right = 0; right < nums.length; right++) {
midSum += nums[right];
while (midSum > sum - x && right >= left) {
midSum -= nums[left++];
}
if (midSum == sum - x) {
ans = Math.min(ans, nums.length - (right - left + 1));
}
}
return ans == Integer.MAX_VALUE ? -1 : ans;
}
}