【滑动窗口】将 x 减到 0 的最小操作数

将 x 减到 0 的最小操作数

  • 将 x 减到 0 的最小操作数
    • 题目
    • 思路讲解
    • 代码书写

将 x 减到 0 的最小操作数

题目

题目链接: 将 x 减到 0 的最小操作数

思路讲解

按照题目的思路去做这一题是非常恶心的, 因此我们采用正难则反思路. 将问题转换为: 求中间某一个最长的数组长度, 使其和为sum - x, 其中 sum 是数组中所有数的总和

那么此时这个题目就被我们转换为了这一题的类似题目: 长度最小的子数组. 他这里是求长度最小的大于等于的, 我们这里就是求长度最大的只能等于的, 那么这一题是否也能用滑动窗口呢? 我们需要进行暴力优化看看

首先我们的暴力思路就是, 枚举所有子数组, 看看什么时候和为 target = sum - x, 并且找出长度最大值.

在这里插入图片描述

那此时有一个问题, 如果我的 target = 1, 此时遇到了下面的这个情况, 还有没有必要后走?

在这里插入图片描述

很明显没有必要了, 你这个时候区间里面的和都 > 1了, 你再往后加那就还更大, 怎么可能等于 target 呢? 当然这里依旧是由于本题有正整数的性质, 因此是可以这样优化的.

所以我们首先可以知道的是, right 是不一定要遍历完的, 当总和比 target 大后, 就可以直接停了.

接下来就是下一个问题, right 有没有必要回到 left 再次遍历呢? 我们依旧是看例子

在这里插入图片描述

当然也是没有必要的, 因为你要求区间里面的和至少要 target. 你刚刚区间, 就恰好是 >= target 的边界. 也就是说, 左边的值应该都是 <= target 的, 也就是下面这个图蓝色区间的和, 肯定是小于 target 的. 因为是正好加了右侧指针的值才 >= target 停下的

!在这里插入图片描述

那你这个时候, 回去重新走一次, 这不是有病吗? 你肯定还是要走回到 4 这个位置的, 那你回去干什么呢? 因此我们可以推断出, left 和 right 是可以同向移动的, 那么就是经典的滑动窗口问题

因此我们还是老套路, 进行三步走

  1. 进窗口: 很明显, 我们需要将 right 指向的值放入到 sum 里进行维护

  2. 条件判断 + 出窗口: 出窗口, 主要就是 sum 太大了, 就需要出窗口, 出到 sum <= target 的时候就可以了.

  3. 更新结果: 结果的更新, 可以说是最好写的一个部分, 你要什么, 你就在什么时候更新. 我们要的是 sum = target 的长度, 那我们就在 sum = target 的时候更新长度不就行了?

    当然, 更新结果的难点在于你把他放哪, 我们这里是在条件判断走完的时候, 才可能遇到 sum == target 的情况, 因此就在那里更新即可.

但是这个题看似简单, 实际上有非常多的细节问题, 还是非常恶心的, 我们依次来看

  1. 如果刚开始算出 target < 0, 那么此时我们要在一个正整数数组里面找小于 0 的区间, 肯定不可能, 直接返回. 如果不返回, 中间会因为 sum 恒大于 target 从而导致 left 一直出窗口, 最后越界

    此时可能有人问了, target = 0 呢? 实际上这个是合理的, 我们找一个区间, 一个数字都不包含, 那不就是 0 了吗, 因此这个是合理的. 但此时又引出了一个细节问题

  2. 我们要找一个区间, 一个数字都不包含, 此时要求区间长度是 0, 那么我们能用 right - left + 1 这个算法来算长度吗? 很明显就不行了, 我们只能使用 right - left, 并且由于这个设定, 我们的更新结果, 必须放在 right++ 的后面.

    如果不放在 right++ 的后面会导致一个什么问题?

    假设数组里面只有一个 1, target = 0. 也就是我需要找一个长度为 0 的区间. 此时 left 会先到外面, 而 right 还指向着 1 这个数字

    在这里插入图片描述

    此时很明显是不合理的, 而此时我们就需要等 right 出来后, 移动一下, 随后我们就可以进行计算了.

    假如使用的是 right - left + 1, 此时还正好就可以处理掉这种情况, 因为 + 1 相当于直接替代了 right 的一次 ++, 也不会出现问题.

  3. 中间的 length 我们可以赋值一个非法值, 例如 -1. 因为如果找不到等于 target 的区间, 那么最后我们需要返回 -1. 如果设定为 0 的话, 由于 0 是合法的, 我们不能确定这个 0 是不是正确的结果. 因此设定一个非法值方便我们判断.

  4. 我们求出的最大长度并不是答案, 而是我们通过思路转换后的目标值, 题目要求的是最小个数, 因此我们要用数组长度 - 目标值, 就可以得到最终答案了. 正难则反虽然好, 但是如果忘记了把结果也反过来, 那就白搭.

代码书写

class Solution {public int minOperations(int[] nums, int x) {// 先求 targetint n = nums.length, numSum = 0;for(int i = 0; i < n; i++) numSum += nums[i];int target = numSum - x;System.out.println(target);if(target < 0) return -1;// 滑动窗口int sum = 0, length = -1, left = 0, right = 0;while(right < n){// 进窗口sum += nums[right];// 条件判断 + 出窗口while(sum > target){sum -= nums[left++];}right++;// 更新结果if(sum == target) length = Math.max(length, right - left);}// 返回结果记得取反, 同时注意细节问题return length == -1 ? length : n - length;}
}

如果有人的思路是在出窗口的时候更新结果, 那么大概率代码如下

while(right < n){// 进窗口sum += nums[right];// 条件判断 + 出窗口while(sum >= target){// 更新结果if(sum == target) length = Math.max(length, right - left + 1);sum -= nums[left++];}right++;
}

此时我们只需要一个非常简单而又极端的例子就可以告诉你为什么这样不行, 假设数组里面只有一个 1, target = 0. 也就是我需要找一个长度为 0 的区间.

那么首先我的 left 就会指向 1, 然后出窗口到数组外面, 此时由于 sum == target, 循环继续, 并且此时会更新结果, 但很明显此时再进行出窗口, 就直接越界了.

因此我们的循环条件, 就不能包含等于的情况, 因为在找 target = 0 的时候, 会在sum = 0, 即 left 和 right 在同一个位置的时候还继续出窗口, 导致越界.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/415632.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hyperf json-rpc

安装 安装docker hyperf 安装 hyperf-rpc-server-v8 &#xff08;服务端&#xff09; docker run --name hyperf-rpc-server-v8 \ -v /www/docker/hyperf-rpc-server:/data/project \ -w /data/project \ -p 9508:9501 -it \ --privileged -u root \ --entrypoint /bin/sh \…

Unity学习路线

目录 一、Unity官方推荐路线二、AI总结的学习路线1、Unity学习路线图&#xff08;文言一心&#xff09;一、基础入门&#xff08;初级&#xff09;二、进阶提升&#xff08;中级&#xff09;三、高级深入&#xff08;高级&#xff09;四、专家级探索 注意事项 2、Unity学习路线…

【2024 CCF编程能力等级认证(GESP)C++ 】 计算机基础知识

目录 1. 引言2. 计算机系统结构2.1 中央处理器&#xff08;CPU - Central Processing Unit&#xff09;2.1.1 运算器 2.1.2 控制器2.1.3 性能指标2.2 存储器2.3 输入设备2.4 输出设备 3. 计算机系统层次结构4. 操作系统4.1 操作系统分类4.2 操作系统常见操作4.2.1 基本开关机操…

Mqtt消费端实现的几种方式

此处测试的mqtt的Broker是使用的EMQX 5.7.1&#xff0c;可移步至https://blog.csdn.net/tiantang_1986/article/details/140443513查看详细介绍 一、方式1 添加必要的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spr…

直播相关概念

文章目录 1、腾讯云直播2、直播&#xff1a;视频直播3、常用的直播组合&#xff1a;4、推流&#xff1a;主播通过推流地址进行视频的推送5、拉流&#xff1a;观众通过拉流地址进行视频的播放6、准备工作6.1、进入腾讯云直播 1、腾讯云直播 直播即时聊天&#xff1a;打赏 文字 …

Linux运维--iptables防火墙命令以及端口号等详解(全)

Linux之iptable防火墙命令以及端口号等详解&#xff08;全&#xff09; 在Linux系统中&#xff0c;你可以使用firewalld和iptables来管理和设置防火墙规则。Firewalld是一个动态管理防火墙的工具&#xff0c;而iptables是一个更底层的工具&#xff0c;可以直接配置Linux内核的…

【重学 MySQL】一、数据库概述

【重学 MySQL】一、数据库概述 为什么要使用数据库数据库与数据库管理系统数据库&#xff08;Database&#xff09;数据库管理系统&#xff08;DBMS&#xff09;数据库与数据库管理系统的关系数据库是数据存储的容器数据库管理系统是数据库的管理者相互依存的关系数据库系统的组…

【网络安全】服务基础第一阶段——第六节:Windows系统管理基础---- DNS部署与安全

计算机智能识别并用IP地址定位&#xff0c;例如我们想要访问一个网页&#xff0c;其实是只能使用这个网页的IP地址&#xff0c;即四位的0&#xff5e;255来访问&#xff0c;但这一串数字难以记忆&#xff0c;于是就有了DNS&#xff0c;将难以记忆的数字转化为容易记忆的域名&am…

Elasticsearch 介绍

1、课程介绍 1.1 ES 8.x 演化进程 版本号发布日期多少个次要版本迭代历时8.02022年2月11日&#xff1f;至今7.02019年4月11日17个次要版本34个月6.02017年11月15日8个次要版本17个月5.02016年10月27日6个次要版本13个月 2、Elasticsearch 是什么 2.1 概念 2.1.1 标准定义 …

文件上传的学习

文件上传漏洞 文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷&#xff0c;而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马&#xff0c;病毒&#xff0c;恶意脚本或者WebShell等。“文件上传”本身没有…

计算机二级 C程序设计(2020B场)全解

A选项&#xff1a;C语言中&#xff0c;一共有3种结构。分别是顺序结构、选择结构&#xff08;else-if语句&#xff09;、循环结构&#xff08;for、while语句&#xff09;。因此&#xff0c;C语言具有结构化特征。 B选项&#xff1a;不仅能解决简单问题&#xff0c;3种基本结构…

WPF MVVM如何在ViewModel直接操作控件对象

早些年在WPF中使用COM组件时&#xff0c;需要在ViewModel中操作COM组件中的控件对象&#xff0c;但是这个控件对象又不支持绑定&#xff0c; 后面的解决办法是在窗口加载时&#xff0c;将控件对象以参数传递到Loaded事件的处理命令中&#xff0c;然后将这个对象记录下来&#…

Ubuntu 18.04升级gclibc为2.28版本

一、查看系统支持的 GLIBC 版本号 ​strings /lib/x86_64-linux-gnu/libc.so.6 | grep GLIBC_出现以下&#xff0c;说明到2.27版本&#xff0c;没有2.28版本&#xff0c;所以我们需要手动安装 GLIBC_2.2.5 GLIBC_2.2.6 GLIBC_2.3 GLIBC_2.3.2 GLIBC_2.3.3 GLIBC_2.3.4 GLIBC_…

Docker入门笔记

Docker 文章目录 Docker1. 下载 &#xff08;centos&#xff09;2. 部署 MySQL3. 常用命令4. 数据卷5. 自定义镜像6. Java 项目部署 1. 下载 &#xff08;centos&#xff09; 卸载旧版 yum remove docker \docker-client \docker-client-latest \docker-common \docker-lates…

84、 k8s的pod基础+https-harbor

一、pod基础&#xff1a; pod进阶&#xff1a;探针&#xff08;面试必问—扩缩容&#xff0c;挂载&#xff09; 1.1、pod的定义 pod是k8s里面的最小单位&#xff0c;pod也是最小运行容器的资源对象。 容器时基于pod在k8s集群当中工作。 在k8s集群当中&#xff0c;一个pod就…

第二阶段:机器学习经典算法-02决策树与随机森林-1.决策树概述

该视频主要讲述了决策树与随机森林算法的基本概念和构造过程。决策树是一个树形结构&#xff0c;用于进行一系列的决策&#xff0c;可以用于分类和回归问题。随机森林算法是基于决策树的集成学习算法&#xff0c;通过构建多棵决策树并结合它们的预测结果来提高分类准确率。视频…

asp.net core web api项目添加自定义中间件

前言 在asp.net core web api项目中&#xff0c;默认提供了很多的中间件&#xff0c;比如访问静态文件中间件UseStaticFiles&#xff0c;跨域配置中间件UseCors&#xff0c;路由中间件UseRouting,身份验证中间件UseAuthentication。 那么如何添加一些自定义的中间件呢。 需求…

java SpringBoot 使用ijpay对接微信支付-商家转账到零钱

使用的maven版本&#xff1a;2.9.11 由于ijpay中提供的实体类没有设置回调参数的属性&#xff0c; 这里是自定义一个实体类:InitiateBatchTransferRequest代码如下&#xff1a; package com.foo.web.controller.pay.wxpay;import com.ijpay.wxpay.model.v3.TransferDetailInput…

【办公软件】Excel如何开n次方根

在文章&#xff1a;【分立元件】电阻的基础知识中我们学习电阻值、电阻值容差标注相关标准。知道了标准将电阻值标准数列化。因此电阻值并非1Ω、2Ω、3Ω那样的整数&#xff0c;而是2.2Ω、4.7Ω那样的小数。 这是因为电阻值以标准数(E系列)为准。系列的“E”是Exponent(指数)…

react vant 在使用dialog.confirm取消报错 Uncaught (in promise) undefined

项目场景&#xff1a; 在使用react做移动端开发时&#xff0c;需要使用Dialog.confirm确认框来做弹框选项&#xff0c;这是在操作中非常常用的一种场景。 问题描述 在列表中&#xff0c;使用弹框时&#xff0c;点击取消时&#xff0c;语法报错&#xff1b;导致后面再触发弹框…