算法刷题:将 x 减到 0 的最小操作数

.

在这里插入图片描述

题目链接

将 x 减到 0 的最小操作数

题目详情

在这里插入图片描述

题目解析

正面做这道题比较难,我们可以进行逆向思维
将这道题理解为:
求数组中,最长的子数组,且子数组中的和为sum-x,其中sum为数组的总长度
那么问题就很简单了,接下来,我们利用滑动窗口来解决这个问题

滑动窗口

在这里插入图片描述

定义指针及其他变量

int left = 0,right = 0,//滑动窗口所需要的两个同向指针
n = nums.length,//数组的长度
ret = -1,//默认返回值,子数组的最大长度
strsum = 0;//子数组的和
int sum = 0;//数组的和
int tmp = sum-x;//子数组需要满足的和

进窗口

记录当前子数组的总和,即将strsum 加上right位置的值
strsum+=nums[right];

判断

判断当前子数组的总和是否大于子数组需要满足的和tmp

出窗口

如果strsum 大于tmp,则需要将子数组最左边的值移除子数组
strsum-=nums[left++];

更新结果

当strsum 等于tmp的时候,则需要更新子数组的最大长度,
ret = Math.max(ret,right-left+1);

我的答案

class Solution {
    public int minOperations(int[] nums, int x) {
        //将问题转化为,求最长字串,且字串的和为sum-x
        //求和
        int sum = 0;
        for(int a :nums){
            sum+=a;
        }
        int tmp = sum-x;
        if(tmp<0) return -1;
        //定义指针
        int left = 0,right = 0,n = nums.length,ret = -1,strsum = 0;
        for(;right<n;right++){
            //进窗口
            strsum+=nums[right];
            //判断
            while(strsum>tmp){
                //出窗口
                strsum-=nums[left++];
            }
            if(strsum==tmp){
                //更新结果
                ret = Math.max(ret,right-left+1);
            }
        }
        //返回结果
        return ret ==-1?-1:n-ret;
    }
}
  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值