在做题中学习(47):将x减到0的最小操作数

1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)

解法:同向双指针————>滑动窗口

思路:本身令a+b = x且要a+b的长度最短 这种想法需要同时考虑前后,所以把它转变为只考虑一种情况:让a+b足够小————>让sum - a - b 足够大,也就是中间那块子数组最长,问题就转变为:找出一个最大的子数组,且它的sum == target 。而最后要返回的结果为数组总长度 - 最大子数组的长度。

滑动窗口步骤:

1.left = 0,right = 0

2.进窗口————>sum+=nums[right]

3.判断————>sum > target

4.出窗口+重新判断————>sum-=nums[left]

5.更新结果————>如果sum==target,就选出更大的len

class Solution 
{
public:
    int minOperations(vector<int>& nums, int x) 
    {
        //len1 总长度,len2 子数组长度
        //小细节 len2赋为-1 因为后面返回结果时如果求不出len的边界情况 直接返回len2就行
        int len1 = nums.size(), len2 = -1;
        int sum1 = 0, sum2 = 0;
        for(int i=0;i<len1;i++)
        {
            sum1 += nums[i];
        }
        int target = sum1 - x;
        //加判断是因为极端情况sum < x
        if(target < 0)
        {
            return -1;
        }
        for(int left = 0,right = 0;right<len1;)
        {
            //1.进窗口
            sum2 += nums[right];
            //2.判断
            while(sum2 > target)
            {
                //3.出窗口
                sum2 -= nums[left];
                left++;
            }
            //更新结果
            if(sum2 == target)
            {
                len2 = max(len2,right - left + 1);
            }
            right++;
        }
        //返回正确的最小操作数
        int ret = len1 - len2;
        if(len2 == -1)
        {
            return len2;
        }
        else
        {
            return ret;
        }
        

        
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值