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

目录

一.题目描述

二.思路分析

三.代码编写


一.题目描述

将x减到0的最小操作数

 题目要求我们在数组的两端不断地取值,使得取出的数之和等于x,问我们最少需要取几次。

也就是说,在两边取两个区间,使得这两个区间的之和等于x,求这两个区间长度之和最小是多少。

两个区间研究起来比较麻烦,正难则反,我们可以转化为研究两侧区间所围的区间,那么只需找到满足条件的最长区间,这个条件就是区间之和为sum-target(sum是整个数组的和),结果就是数组的长度减去求得的len。

二.思路分析

两层for循环暴力枚举所有的区间,找到符合条件的区间,通过比较得到最长的区间长度,从而得到结果。代码就不具体实现了。

使用滑动窗口优化,首先要证明right不需要回退

 right不断向后移动,当移动到图中位置时,区间之和total>= sum-x, right停了下来,(潜台词是[left, right - 1]区间的和是小于total的)。此时应该判断total是否等于sum-x, 如果是就更新结果。隐含条件:。

按照暴力枚举策略 ,left向后移动一步,right回退。但是最终right还是会回到原处。因为图中大括号对应的区间之和是不满足要求的,right会一直向右移动。故right没有必要往回退,留在原地即可。

 那么此时的区间之和是否小于sum-x呢?不确定,因为可能跳过的是一个很小的数,区间之和仍然>=sum-x,此时right没有必要向后枚举了,因为区间再往后扩展,和肯定大于sum-x了。所以让left继续向后移动,直到total <sum-x时,right再向后移动。

所以判断是一个循环的逻辑,不能用if简单地只判断一次。

三.代码编写

 其中更新结果时total应该等于target,故可以再判断条件成立,出窗口之前判断total是否等于target,如果等于就更新结果。

class Solution {
public:int minOperations(vector<int>& nums, int x) {int sum = 0;for (auto e : nums){sum += e;}int target = sum - x;int n = nums.size();int len = -1;int left = 0, right = 0;int total = 0;//统计窗口内所有数的和while (right < n){//进窗口total += nums[right];//判断while (total >= target){//更新结果if (total == target){len = max(len, right - left + 1);}//出窗口total -= nums[left++];}right++;}return len == -1 ? -1 : n - len;}
};

当你怀着激动的心情提交代码时,发现到第6个用例就挂了

 

 这种错误提示,八成是越界访问了。模拟代码的执行逻辑,最后发现确实是left越界了。原因在于target是个负数,当right移动到n-1位置,left移动到n位置时,total恰好等于0,但还是大于等于target,故还要出窗口,此时left就越界访问报错了。所以targe小于等于0时需要特殊处理。

当target小于0时,直接返回-1,因为所有数都是正整数,不可能有结果。当target=0时,说明sum=x,直接返回数组长度即可。

class Solution {
public:int minOperations(vector<int>& nums, int x) {int sum = 0;for (auto e : nums){sum += e;}//越界情况单独处理int target = sum - x;if (target < 0){return -1;}if (target == 0){return nums.size();}int n = nums.size();int len = -1;int left = 0, right = 0;int total = 0;//统计窗口内所有数的和while (right < n){//进窗口total += nums[right];//判断while (total >= target){//更新结果if (total == target){len = max(len, right - left + 1);}//出窗口total -= nums[left++];}right++;}return len == -1 ? -1 : n - len;}
};

事实上,还可以将更新结果的操作放在while循环外面,这时只需把循环的条件改为total>target。当程序通过while循环的逻辑后,total要么小于target,要么等于target。此时再进行判断,如果等于就更新结果,这样的逻辑会更加简单,而且此时target=0的情况也不会越界访问了。

class Solution {
public:int minOperations(vector<int>& nums, int x) {int sum = 0;for (auto e : nums){sum += e;}//越界情况单独处理int target = sum - x;if (target < 0){return -1;}int n = nums.size();int len = -1;int left = 0, right = 0;int total = 0;//统计窗口内所有数的和while (right < n){//进窗口total += nums[right];//判断while (total > target){//出窗口total -= nums[left++];}//更新结果if (total == target){len = max(len, right - left + 1);}right++;}return len == -1 ? -1 : n - len;}
};

时间复杂度O(n)

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

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

相关文章

idea http request无法识别环境变量

问题描述 创建了环境变量文件 http-client.env.json&#xff0c;然后在*.http 文件中引用环境变量&#xff0c;运行 HTTP 请求无法读取环境变量文件中定义的变量。 事故现场 IDEA 版本&#xff1a;2020.2 2021.2 解决步骤 2020.2 版本环境变量无法读取 2021.2 版本从 2020.…

基于Jenkins自动化部署PHP环境---基于rsync部署

基于基于Jenkins自动打包并部署Tomcat环境_学习新鲜事物的博客-CSDN博客环境 准备git仓库 [rootgit ~]# su - git 上一次登录&#xff1a;五 8月 25 15:09:12 CST 2023从 192.168.50.53pts/2 上 [gitgit ~]$ mkdir php.git [gitgit ~]$ cd php.git/ [gitgit php.git]$ git --b…

SOPC之NIOS Ⅱ实现电机转速PID控制(调用中断函数)

通过FPGA开发板上的NIOS Ⅱ搭建电机控制的硬件平台&#xff0c;包括电机正反转、编码器的读取&#xff0c;再通过软件部分实现PID算法对电机速度进行控制&#xff0c;使其能够渐近设定的编码器目标值。 一、问题与改进 SOPC之NIOS Ⅱ实现电机转速PID控制_STATEABC的博客-CSDN…

npm 卸载 vuecli后还是存在

运行了npm uninstall vue-cli -g&#xff0c;之后是up to date in&#xff0c;然后vue -V&#xff0c;版本号一直都在&#xff0c;说明没有卸载掉 1、执行全局卸载命令 npm uninstall vue-cli -g 2、删除vue原始文件 查看文件位置&#xff0c;找到文件删掉 where vue 3、再…

minion在ubuntu上的搭建步骤

在Ubuntu上搭建MinIO可以按照以下步骤进行&#xff1a; 下载MinIO服务器二进制文件&#xff1a; 通过浏览器访问 https://min.io/download 或使用以下命令获取最新的MinIO二进制文件&#xff1a;wget https://dl.min.io/server/minio/release/linux-amd64/minio赋予二进制文件…

宝藏级画图工具-drawio

今天推荐一款非常好用的免费开源画图工具drawio. Drawio即可以下载安装到本地&#xff0c;也可以在线编辑&#xff0c;在线编辑网址为 https://app.diagrams.net/。 本地版下载地址为https://github.com/jgraph/drawio-desktop/releases 1、支持各类图形 Drawio可以非常便捷…

导数基本概念

定义 f ( x ) − f ( a ) x − a {f(x) - f(a)\over x -a} x−af(x)−f(a)​ 表示 f(x) 函数从 x 到 a 的平均变化率&#xff0c;如果使 x 趋近于 a&#xff0c;则表示函数在 a 点的变化率。 若有以下极限存在&#xff08;定义域不包含a&#xff09;&#xff1a; lim ⁡ x →…

函数式编程-Stream流学习第二节-中间操作

1 Stream流概述 java8使用的是函数式编程模式,如同它的名字一样&#xff0c;它可以用来对集合或者数组进行链状流式操作&#xff0c;让我们更方便的对集合或者数组进行操作。 2 案例准备工作 我们首先创建2个类一个作家类&#xff0c;一个图书类 package com.stream.model;…

Xmake v2.8.2 发布,官方包仓库数量突破 1k

Xmake 是一个基于 Lua 的轻量级跨平台构建工具。 它非常的轻量&#xff0c;没有任何依赖&#xff0c;因为它内置了 Lua 运行时。 它使用 xmake.lua 维护项目构建&#xff0c;相比 makefile/CMakeLists.txt&#xff0c;配置语法更加简洁直观&#xff0c;对新手非常友好&#x…

Rabbitmq的Federation Exchange

(broker 北京 ) &#xff0c; (broker 深圳 ) 彼此之间相距甚远&#xff0c;网络延迟是一个不得不面对的问题。有一个在北京的业务(Client 北京 ) 需要连接 (broker 北京 ) &#xff0c;向其中的交换器 exchangeA 发送消息&#xff0c;此时的网络延迟很小&#xff0c;(C…

使用go语言、Python脚本搭建一个简单的chatgpt服务网站。

使用go语言、Python脚本搭建一个简单的GPT服务网站 前言 研0在暑假想提升一下自己&#xff0c;自学了go语言编程和机器学习相关学习&#xff0c;但是一味学习理论&#xff0c;终究是枯燥的&#xff0c;于是自己弄点小项目做。 在这之前&#xff0c;建议您需要掌握以下两个技…

QtWidgets和QtQuick融合(QML与C++融合)

先放一个界面效果吧&#xff01; 说明&#xff1a;该演示程序为一个App管理程序&#xff0c;可以将多个App进行吸入管理。 &#xff08;动画中的RedRect为一个带有QSplashScreen的独立应用程序&#xff09; 左侧边栏用的是QQuickView进行.qml文件的加载&#xff08;即QtQuick…