滑动窗口--(中篇)
将X减到0的最小操作数

给你一个整数数组 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 <= 1051 <= nums[i] <= 104- `1 <= x <= 109


这里我们可能会觉得正着做去求,会有些困难,可以尝试着反着来做,效果会不一样
算法思路:
题⽬要求的是数组「左端+右端」两段连续的、和为 x 的最短数组,信息量稍微多⼀些,不易理清 思路;我们可以转化成求数组内⼀段连续的、和为 sum(nums) - x 的最⻓数组。此时,就是熟 悉的「滑动窗⼝」问题了。
算法流程:
a. 转化问题:求 target = sum(nums) - x 。如果 target < 0 ,问题⽆解;
b. 初始化左右指针 left = 0 , right = 0 (滑动窗⼝区间表⽰为 [left, right) ,左右区间是否开闭很重 要,必须设定与代码⼀致),记录当前滑动窗⼝内数组和的变量 tmp= 0 ,记录当前满⾜条 件数组的最⼤区间⻓度ret = -1 ;
c. 当 right ⼩于等于数组⻓度时,⼀直循环:
i. 如果 sum < target ,右移右指针,直⾄变量和⼤于等于 target ,或右指针已经移到 头;
ii. 如果 sum > target ,右移左指针,直⾄变量和⼩于等于 target ,或左指针已经移到 头;
iii. 如果经过前两步的左右移动使得 sum == target ,维护满⾜条件数组的最⼤⻓度,并 让下个元素进⼊窗⼝;
d. 循环结束后,如果 ret 的值有意义,则计算结果返回;否则,返回 -1 。
代码如下:
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;}
};
水果成篮
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。
你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
- 你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
- 你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
- 一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。
给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。
示例 1:
输入:fruits = [1,2,1]
输出:3
解释:可以采摘全部 3 棵树。
示例 2:
输入:fruits = [0,1,2,2]
输出:3
解释:可以采摘 [1,2,2] 这三棵树。
如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。
示例 3:
输入:fruits = [1,2,3,2,2]
输出:4
解释:可以采摘 [2,3,2,2] 这四棵树。
如果从第一棵树开始采摘,则只能采摘 [1,2] 这两棵树。
示例 4:
输入:fruits = [3,3,3,1,2,1,1,2,3,3,4]
输出:5
解释:可以采摘 [1,2,1,1,2] 这五棵树。
提示:
1 <= fruits.length <= 1050 <= fruits[i] < fruits.length
题目解析
转化成找出一个最长的子数组的长度,子数组中不能超过两种水果的类型

算法思路:**
研究的对象是⼀段连续的区间,可以使⽤「滑动窗⼝」思想来解决问题。
让滑动窗⼝满⾜:窗⼝内⽔果的种类只有两种。
做法:右端⽔果进⼊窗⼝的时候,⽤哈希表统计这个⽔果的频次。这个⽔果进来后,判断哈希表的 ⼤⼩:
▪ 如果⼤⼩超过 2:说明窗⼝内⽔果种类超过了两种。那么就从左侧开始依次将⽔果划出窗 ⼝,直到哈希表的⼤⼩⼩于等于 2,然后更新结果;
▪ 如果没有超过 2,说明当前窗⼝内⽔果的种类不超过两种,直接更新结果 ret。
算法流程:
a. 初始化哈希表 hash 来统计窗⼝内⽔果的种类和数量;
b. 初始化变量:左右指针 left = 0,right = 0,记录结果的变量 ret = 0;
c. 当 right ⼩于数组⼤⼩的时候,⼀直执⾏下列循环:
i. 将当前⽔果放⼊哈希表中;
ii. 判断当前⽔果进来后,哈希表的⼤⼩:
• 如果超过 2:
◦ 将左侧元素滑出窗⼝,并且在哈希表中将该元素的频次减⼀;
◦ 如果这个元素的频次减⼀之后变成了 0,就把该元素从哈希表中删除;
◦ 重复上述两个过程,直到哈希表中的⼤⼩不超过 2;
iii. 更新结果 ret;
iv. right++,让下⼀个元素进⼊窗⼝;
d. 循环结束后,ret 存的就是最终结果。
C++ 算法代码(使⽤容器):
class Solution
{
public:int totalFruit(vector<int>& f) {unordered_map<int, int> hash; // 统计窗⼝内出现了多少种⽔果int ret = 0;for(int left = 0, right = 0; right < f.size(); right++){hash[f[right]]++; // 进窗⼝while(hash.size() > 2) // 判断{// 出窗⼝
hash[f[left]]--;if(hash[f[left]] == 0)hash.erase(f[left]);left++;}ret = max(ret, right - left + 1);}return ret;}
};
但是一直插入和删除的时间复杂度会提高,所以根据题目提示是有范围的,可以考虑用数组来模拟哈希表
代码如下(⽤数组模拟哈希表):
class Solution {
public:int totalFruit(vector<int>& fruits) {int hash[100001]={0};int ret=0;for(int left=0,right=0,kinds=0;right<fruits.size();right++){if(hash[fruits[right]]==0) kinds++;hash[fruits[right]]++;while(kinds>2){hash[fruits[left]]--;if(hash[fruits[left]]==0) kinds--;left++;}ret=max(ret,right-left+1);}return ret;}
};
相关文章:
滑动窗口--(中篇)
将X减到0的最小操作数 给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。 如果可以将 x 恰好 减到 0 ,返…...
Java性能调优:实战技巧与最佳实践
引言 Java作为企业级应用开发的首选语言之一,其性能直接影响到系统的响应速度和用户体验。性能调优是一项复杂的工作,涉及多个层面的知识和技术。本文将通过具体的示例,探讨一些常见的性能调优技巧及最佳实践。 1. 了解你的应用程序 示例&…...
排版套料系统设计说明
先上效果图 项目地址 1.产品介绍 产品名称:StreamFit 智能排版套料系统 主要功能: 智能排版优化 功能描述:StreamFit 利用先进的算法技术,自动对各类材料(如布料、金属板材、纸张等)进行高效排版布局&am…...
算法修炼之路之二分查找
目录 一:三大二分介绍及模板 1.普通二分 2.查找左右边界的二分及模板 二:LeetCode OJ练习 1.第一题 2.第二题 3.第三题 4.第四题 5.第五题 6.第六题 一:三大二分介绍及模板 1.普通二分 这里通过一道题来引出普通二分及模板 LeetCode_704 二分查找 画图分析: 具体代…...
OpenAI预计明年将推出“代理”系统
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
每日OJ题_牛客_重排字符串_贪心_C++_Java
目录 牛客_重排字符串_贪心 题目解析 C代码 Java代码 牛客_重排字符串_贪心 重排字符串 (nowcoder.com) 描述: 小红拿到了一个只由小写字母组成的字符串。她准备把这个字符串重排(只改变字母的顺序,不改变数量) …...
Python 进阶部分详细整理
1. 面向对象编程(OOP) 面向对象编程 (OOP) 是一种通过将程序中的数据和功能封装为对象的编程范式。OOP 基于四个核心概念:类与对象、继承、封装与多态。 类与对象 类(Class):类是创建对象的蓝图或模板。它…...
[ RK3566-Android11 ] 关于移植 RK628F 驱动以及后HDMI-IN图像延迟/无声等问题
问题描述 由前一篇文章https://blog.csdn.net/jay547063443/article/details/142059700?fromshareblogdetail&sharetypeblogdetail&sharerId142059700&sharereferPC&sharesourcejay547063443&sharefromfrom_link,移植HDMI-IN部分驱动后出现&a…...
【黑马点评】 使用RabbitMQ实现消息队列——2.使用RabbitMQ监听秒杀下单
2 使用RabbitMQ实现消息队列 2.1 修改\hm-dianping\pom.xmlpom.xml文件 添加RabbitMQ的环境 <!-- RabbitMQ--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </depe…...
业务封装与映射 -- OTUk/ODUk/OPUk开销帧结构
开销是为了保证净荷正常、灵活传送所必须附加的供网络运行、管理和维护(OAM)使用的字节。 OTN电层开销包括OTUk开销、ODUk开销、OPUk开销、OTUCn开销、ODUCn开销、OPUCn开销和帧对齐开销。 SM开销属于OTU开销,占用3个字节;PM开销…...
Vim基本用法
Vim用法 一、基本模式 1. 普通模式(Normal Mode) 移动光标 基本移动:使用方向键(h左移、j下移、k上移、l右移),也可以使用 H(移到屏幕顶部)、M(移到屏幕中间ÿ…...
python 实现Tarjan 用于在有向图中查找强连通分量的算法
Tarjan 用于在有向图中查找强连通分量的算法介绍 Tarjan算法是一种用于在有向图中查找强连通分量的高效算法,由Robert Tarjan在1972年提出。强连通分量是指在有向图中,如果从顶点u到顶点v以及从顶点v到顶点u都存在一条路径,那么顶点u和顶点v…...
Qt开发技巧(十五)字符串去除空格,跨网段搜索不生效,设置图片显示失败问题,表格视图的批量删除,主动判断字串编码,开启向前查询的属性,画家类载入html来绘制
继续讲一些Qt开发中的技巧操作: 1.字符串去除空格 我们经常会遇到字符串重去除空格的情况,对于QString去除空格,有多种场景,可能需要去除左侧、右侧、所有等位置的空格; //字符串去空格 -1移除左侧空格 0移除所有空格…...
【机器学习】智驭未来:探索机器学习在食品生产中的革新之路
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀目录 🔍1. 引言:探索机器学习在食品生产中的革新之路📒2. 机器学习在食品质量控制中的应用🌞实…...
Ubuntu 安装CUDA并使用Docker配置Pytorch环境
文章目录 参考安装顺序Nvidia GPU driverDockerNvidia Container ToolkitDocker PyTorch 1. Nvidia GPU Driver2. Docker 安装(使用apt存储库进行安装)3. Nvidia Container Toolkit3.1 Docker测试GPU 参考 安装顺序 Nvidia GPU driver Docker Nvidia…...
【论文阅读】Simulating 500 million years of evolution with a language model
Simulating 500 million years of evolution with a language model 1、概述 展示了语言模型在蛋白质设计和进化模拟方面的能力。通过对 ESM3 模型的研究,发现其能够生成与自然蛋白质差异较大且具有功能的新蛋白质,如新型绿色荧光蛋白(GFP),表明语言模型可以达到自然进化…...
detectron2/layers源码笔记
from .wrappers import ( BatchNorm2d, Conv2d, #在torch.conv2d的基础上集成了norm层和activation层 ConvTranspose2d, cat, interpolate, Linear, nonzero_tuple, #nonzero_tuple(x)得到tuple of 每个维度的索引 cross_entropy, empty_input_loss_func…...
LLM+知识图谱新工具! iText2KG:使用大型语言模型构建增量知识图谱
iText2KG是一个基于大型语言模型的增量知识图谱构建工具,通过从文本文档中提取实体和关系来逐步构建知识图谱。该工具具有零样本学习能力,能够在无需特定训练的情况下,在多个领域中进行知识提取。它包括文档提炼、实体提取和关系提取模块&…...
React基础-快速梳理
React介绍 React由Meta公司开发,是一个用于构建Web和原生交互界面的库 React的优势 相较于传统基于DOM开发的优势 组件化的开发方式不错的性能 相较于其它前端框架的优势 丰富的生态跨平台支持 开发环境创建 create-react-app是一个快速创建React开发环境的…...
H.264编解码 - NALU详解
一、概述 NALU(Network Abstraction Layer Unit)是H.264编解码中的一个重要概念。H.264是一种视频压缩标准,将视频数据分割成一系列的NALU。每个NALU都是一个独立的数据单元,包含视频压缩后的一个片段。每个NALU都有自己的起始码和长度前缀,用于标识NALU的起始位置和长度。…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
