LeetCode 1658.将x减到0的最小操作数

1、题目描述

给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。

如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。

2、算法思路

        我们可以通过问题转化,把问题转化成在nums的一段连续的区间中,target = sum - x,我们只需要在在nums中找到这个区间里面最大的元素的长度等于targer。

3、算法流程

 3.1 求nums中的总数和 sum。如果sum<x,问题无解,返回-1,如果sum = x,返回nums.length。

3.2 设置左右指针,目的是通过滑动窗口来寻找nums中的值等于target

3.3 进窗口        每个rigth的元素进入窗口

       判断           判断窗口中的值是否大于target

        出窗口      如果大于,左指针出窗口

        更新结果     如果窗口内元素的总值大于target,更新ret,通过比较

4、算法代码

class Solution {
    public int minOperations(int[] nums, int x) {
        int sum = 0;
        for(int i : nums) sum += i; //计算sums中元素的总和
        if(sum < x) return -1;//表示区间内的值加起来也达不到x
        if(sum == x) return nums.length; 
        int targer = sum -x;//连续的区间需要计算达到的目标值
        int ret = Integer.MIN_VALUE;//ret初始化,表示任意一个值都可以替换它
        int temp = 0,n = nums.length;
        for(int left =0,right = 0;right < n;right++){
            temp += nums[right];//进窗口
            while(temp > targer){ //判断
                temp -= nums[left];//出窗口
                left++;
            }
            if(temp == targer){//更新结果
                ret = Math.max(ret,right - left+1);
            }
        }
        if(ret == Integer.MIN_VALUE){
            return -1;
        }else{
            return n -ret;
        }

    }
}

5、运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值