day115—同向双指针—将x减到0的最小操作数(LeetCode-1658)

题目描述

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

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

示例 1:

复制代码
输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0 。

示例 2:

复制代码
输入:nums = [5,6,7,8,9], x = 4
输出:-1

示例 3:

复制代码
输入:nums = [3,2,20,1,1,3], x = 10
输出:5
解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 104
  • 1 <= x <= 109

解决方案:

核心转换思路

  1. 原本问题:从数组两端 删除元素,使删除的元素和等于 x

  2. 等价问题:找到数组中间一个连续子数组 ,使其和等于 total - x

  3. 这样两端删除的次数最少 = 数组总长度 - 中间子数组长度最大

算法步骤

  1. 计算数组总和 total

  2. 计算中间子数组的目标和:midSum = total - x

  3. 如果 midSum < 0:不可能,返回 -1

  4. 如果 midSum == 0:需要删除所有元素,返回数组长度

  5. 用滑动窗口找和为 midSum最长连续子数组

  6. 如果找到:返回 len - 最长子数组长度

  7. 如果没找到:返回 -1

滑动窗口细节

  • 维护窗口 [left, i]的和为 sum

  • sum > midSum时,从左收缩窗口

  • sum == midSum时,更新最大窗口长度

  • 窗口长度越大,两端删除的元素就越少

时间复杂度:O(n),每个元素最多进出窗口一次

举例

cpp 复制代码
nums = [1,1,4,2,3], x = 5
total = 11, midSum = 6
最长和为6的子数组:[1,1,4],长度=3
最小操作次数 = 5 - 3 = 2
删除两端元素:[2,3]

结果:返回删除两端元素的最少操作次数,如果不可能则返回 -1。

函数源码:

cpp 复制代码
class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int len =nums.size();
        int ans=0;
        int left=0;

        int midSum=accumulate(nums.begin(),nums.end(),0) - x;//求和
        if(midSum<0)   return -1;
        if(midSum==0)  return len;

        int sum=0;
        for(int i=0;i<len;i++){
            sum+=nums[i];
            while(sum>midSum){
                sum-=nums[left];
                left+=1;
            }
            if(sum==midSum) ans=max(ans,i-left+1);
        }
        return ans==0? -1:len-ans;
    }

};
相关推荐
2401_831824961 小时前
代码性能剖析工具
开发语言·c++·算法
Sunshine for you2 小时前
C++中的职责链模式实战
开发语言·c++·算法
qq_416018722 小时前
C++中的状态模式
开发语言·c++·算法
2401_884563242 小时前
模板代码生成工具
开发语言·c++·算法
2401_831920742 小时前
C++代码国际化支持
开发语言·c++·算法
m0_672703313 小时前
上机练习第51天
数据结构·c++·算法
ArturiaZ3 小时前
【day60】
算法·深度优先·图论
2401_851272993 小时前
自定义内存检测工具
开发语言·c++·算法
☆5663 小时前
C++中的命令模式
开发语言·c++·算法
仰泳的熊猫3 小时前
题目2577:蓝桥杯2020年第十一届省赛真题-走方格
数据结构·c++·算法·蓝桥杯