题⽬要求的是数组「左端+右端」两段连续的、和为 x 的最短数组;我们可以转化成求数组内⼀段连续的、和为 sum(nums) - x 的最⻓数组。
a. 转化问题:求 target = sum(nums) - x 。如果 target < 0 ,问题⽆解;
b. 初始化左右指针 l = 0 , r = 0 (滑动窗⼝区间表⽰为 [l, r) ,左右区间是否开闭很重 要,必须设定与代码⼀致),记录当前滑动窗⼝内数组和的变量 sum = 0 ,记录当前满⾜条 件数组的最⼤区间⻓度 maxLen = -1 ;
c. 当 r ⼩于等于数组⻓度时,⼀直循环:
i. 如果 sum < target ,右移右指针,直⾄变量和⼤于等于 target ,或右指针已经移到 头;
ii. 如果 sum > target ,右移左指针,直⾄变量和⼩于等于 target ,或左指针已经移到 头;
iii. 如果经过前两步的左右移动使得 sum == target ,维护满⾜条件数组的最⼤⻓度,并 让下个元素进⼊窗⼝;
d. 循环结束后,如果 maxLen 的值有意义,则计算结果返回;否则,返回 -1 。
class Solution
{
public:
int minOperations(vector<int>& nums, int x)
{
int sum = 0;
for(int a : nums)
sum += a;
int target = sum - x;
// 细节问题
if(target < 0)
return -1;
int ret = -1;
for(int left = 0, right = 0, tmp = 0; right < nums.size(); right++)
{
tmp += nums[right]; // 进窗⼝
while(tmp > target) // 判断
tmp -= nums[left++]; // 出窗⼝
if(tmp == target) // 更新结果
ret = max(ret, right - left + 1);
}
if(ret == -1)
return ret;
else
return nums.size() - ret;
}
};