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

文章介绍了一种使用双指针优化算法来解决在数组中找到最小区间,使得区间内元素之和等于给定值x的方法。通过避免无效的区间枚举,将时间复杂度降低到O(n),空间复杂度为O(1)。代码示例分别用Java、C++和Python实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解法一:双指针

首先,每次操作可以移除数组 nums 最左边或最右边的元素,那么相当于求出 l 和 r l和r lr使得 [ 0 , l ] + [ r , n − 1 ] [0, l]+[r,n-1] [0,l]+[r,n1]之间所有元素之和等于 x x x,并且元素个数最少。我们可以通过双重循环枚举 l 和 r 变量 l和r变量 lr变量的取值来计算出最小的答案。时间复杂度为 O ( n 2 ) O(n^2) O(n2)


但其实很多区间是不合法的,比如若 [ 0 , l ] [0, l] [0,l]的和已经大于x,那么对于当前的 l l l就不用再去枚举 r r r。通过这种思路,我们使用双指针进行优化。


在这里插入图片描述 R 和 L R和L RL指针移动的次数都为n,因此整个时间复杂度为 O ( n ) O(n) O(n)。对于第一次移动来说,先让 L L L指针移动是为了直接计算右边区间长度为0的情况。对于 − 1 -1 1的情况,若我们的ans最后大于n,那么必然不合法。

class Solution {
    public int minOperations(int[] nums, int x) {
        int sum = Arrays.stream(nums).sum(), n = nums.length, l = n - 1, ans = n + 5;
        for (int r = n - 1; r >= 0; r--) {
            while (sum > x && l >= 0) sum -= nums[l--];
            if (sum == x) ans = Math.min(ans, n - r + l); 
            sum += nums[r]; 
        }
        return ans > n ? -1 : ans;
    }
}
class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int sum = accumulate(nums.begin(), nums.end(), 0), n = nums.size(), l = n - 1, ans = n + 5;
        for (int r = n - 1; r >= 0; r--) {
            while (sum > x && l >= 0) sum -= nums[l--];
            if (sum == x) ans = min(ans, n - r + l);
            sum += nums[r]; 
        }
        return ans > n ? -1 : ans;
    }
};
class Solution:
    def minOperations(self, nums: List[int], x: int) -> int:
        n = len(nums)
        s, l, ans = sum(nums), n - 1, n + 5
        for r in range(n - 1, -1, -1):
            while s > x and l >= 0:
                s -= nums[l]
                l -= 1
            if s == x:
                ans = min(ans, n - r + l)
            s += nums[r]
        return -1 if ans > n else ans
         

如果有问题,欢迎评论区交流, 如果有帮助到你,请给题解点个赞和收藏哈~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值