当前位置: 首页 > news >正文

滑动窗口(4)—将x减到0的最⼩操作数

文章目录

  • 题目解析
    • 方法一:滑动窗口
    • 方法二:哈希表 + 前缀和
    • 附Java代码

力扣题目:将x减到0的最⼩操作数

题目解析

在这里插入图片描述

方法一:滑动窗口

算法思路:
题⽬要求的是数组「左端+右端」两段连续的、和为
sum(nums) - x
的最⻓数组。此时,就是熟
悉的「滑动窗⼝」问题了。

 class Solution 
{
 public:
 int minOperations(vector<int>& nums, int x) 
{
 int sum = 0;
 for(int a : nums) sum += a;
 int target = sum - x;
 // 
细节问题
 
if(target < 0) return -1;
 int ret = -1;
 for(int left = 0, right = 0, tmp = 0; right < nums.size(); right++)
 {
 tmp += nums[right]; // 
进窗⼝
 
while(tmp > target) // 
判断
 
tmp -= nums[left++]; // 
出窗⼝
 
if(tmp == target) // 
更新结果
 
ret = max(ret, right - left + 1);
 }
 if(ret == -1) return ret;
 else return nums.size() - ret;
 }
 };

方法二:哈希表 + 前缀和

我们可以将问题转换为求中间连续子数组的最大长度,使得子数组的和为 x=sum(nums)−x。

定义一个哈希表 vis,其中 vis[s] 表示前缀和为 s 的最小下标。

遍历数组 nums,对于每个元素 nums[i],我们先将 nums[i] 加到前缀和 s 上,如果哈希表中不存在 s,则将其加入哈希表,其值为当前下标 i。然后我们判断 s−x 是否在哈希表中,如果存在,则说明存在一个下标 j,使得 nums[j+1,…i] 的和为 x,此时我们更新答案的最小值,即 ans=min(ans,n−(i−j))。

遍历结束,如果找不到满足条件的子数组,返回 −1,否则返回 ans。

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        x = accumulate(nums.begin(), nums.end(), 0) - x;
        unordered_map<int, int> vis{{0, -1}};
        int n = nums.size();
        int ans = 1 << 30;
        for (int i = 0, s = 0; i < n; ++i) {
            s += nums[i];
            if (!vis.count(s)) {
                vis[s] = i;
            }
            if (vis.count(s - x)) {
                int j = vis[s - x];
                ans = min(ans, n - (i - j));
            }
        }
        return ans == 1 << 30 ? -1 : ans;
    }
};


附Java代码

class Solution {
    public int minOperations(int[] nums, int x) {
        int n = nums.length;
        int sum = Arrays.stream(nums).sum();

        if (sum < x) {
            return -1;
        }

        int right = 0;
        int lsum = 0, rsum = sum;
        int ans = n + 1;

        for (int left = -1; left < n; ++left) {
            if (left != -1) {
                lsum += nums[left];
            }
            while (right < n && lsum + rsum > x) {
                rsum -= nums[right];
                ++right;
            }
            if (lsum + rsum == x) {
                ans = Math.min(ans, (left + 1) + (n - right));
            }
        }

        return ans > n ? -1 : ans;
    }
}

相关文章:

  • 基于时间序列分解与XGBoost的交通通行时间预测方法解析
  • x265 编码参数 rdLevel 详细解析
  • buuctf sql注入类练习
  • UITableVIew性能优化概述
  • 【DE2-115】Verilog实现DDS+Quartus仿真波形
  • 【算法】One-Stage检测器与Two-Stage检测器的原理和区别
  • 开启bitlocker使用windows的加密功能
  • (1)VTK环境配置
  • Unity 基于navMesh的怪物追踪惯性系统
  • CAP理论 与 BASE理论
  • RAG文献阅读——用于知识密集型自然语言处理任务的检索增强生成
  • 数据库删除表数据
  • 在C盘新建文本文档
  • Go环境变量配置
  • Qt报错dependent ‘..\..\..\..\..\..\xxxx\QMainWindow‘ 或者 QtCore\QObject not exist
  • QEMU学习之路(7)— ARM64 启动Linux
  • 每天学一个 Linux 命令(16):mkdir
  • 【寻找Linux的奥秘】第四章:基础开发工具(下)
  • 信息学奥赛一本通 1498:Roadblocks | 洛谷 P2865 [USACO06NOV] Roadblocks G
  • Ubuntu 各个常见长期支持历史版本与代号
  • 免费制作微网站/宁波关键词优化平台
  • 河北pc端网站开发/考研培训
  • 网站开发 兼职/职业教育培训机构排名前十
  • 网站站建设建技设术技术/怎么进行推广
  • 大连哪个公司做网站开发的/太原seo哪家好
  • 网站子目录/今天热点新闻事件