LeetCode 1658 将x减到0的最小操作数前缀和 滑动窗口 HERODING的LeetCode之路

Posted HERODING23

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1658 将x减到0的最小操作数前缀和 滑动窗口 HERODING的LeetCode之路相关的知识,希望对你有一定的参考价值。

解题思路:
一道很有意思的前缀和和滑动窗口结合的题目。首先分析题目,既然每次都是从数组的最左边或者最右边减去元素值,那么最后剩下的数一定都是在数组中间的数,那不如把中间的数维护成一个滑动窗口,为了计算方便,再构造一个前缀和数组,这样就不需要不断维护滑动窗口中的求和了。解题过程如下:

  1. 构造前缀和数组,定义滑动窗口左右指针都在第一个位置;
  2. 右指针不断向右移动,利用前缀和计算窗口外的数值之和,直到窗口外之和不小于x;
  3. 如果等于x,更新最小操作数,即滑动窗口外数的个数;
  4. 左指针右移,不断重复1-3,直到右指针遍历所有的位置。

注意一些边界情况,第一是数组总和小于x,那么这个时候直接返回-1,第二是数组总和恰好等于x,也就是滑动窗口大小为0的情况,但是在我的方法中默认大小从1开始,所以需要特别处理,代码如下:

class Solution 
public:
    int minOperations(vector<int>& nums, int x) 
        int n = nums.size();
        vector<int> prefix(n + 1, 0);
        for(int i = 0; i < n; i ++) 
            prefix[i + 1] = prefix[i] + nums[i];
        
        if(prefix[n] < x) 
            return -1;
        
        if(prefix[n] == x) 
            return n;
        
        int left = 0, right = 0;
        int res = INT_MAX;
        while(right < n) 
            while(right < n && prefix[left] + prefix[n] - prefix[right + 1] > x) 
                right ++;     
            
            if(right < n && prefix[left] + prefix[n] - prefix[right + 1] == x) 
                res = min(res, n - right + left - 1);
                right ++;
             
            left ++;
        
        return res == INT_MAX ? -1 : res;
    
;```

 

以上是关于LeetCode 1658 将x减到0的最小操作数前缀和 滑动窗口 HERODING的LeetCode之路的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 1658 将x减到0的最小操作数前缀和 滑动窗口 HERODING的LeetCode之路

Leetcode 1658. Minimum Operations to Reduce X to Zero

uva1658 Admiral

uva 1658 Admiral (最小费最大流)

UVa1658 Admiral (拆点法,最小费用流)

LeetCode 1551. 使数组中所有元素相等的最小操作数