动态维护有效区间:滑动窗口

右指针不断移动获取解,左指针不断移动缩小解范围

左指针的意义非常重要,相当于一个标兵,不断与这个标兵进行比较,如果符合要求,这左指针进行移动,并进行操作,如果不符合要求,则左指针不动,右指针接着寻找符合要求的值。

删除有序数组中的重复项

给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]

暴力解法

一种非常简单的办法就是创建一个新的数组,每次添加元素的时候判断是否已经添加过了

class Solution:def removeDuplicates(self, nums: List[int]) -> int:res = []for v in nums:if v in res:continueres.append(v)return res

但是要求我们原地删除重复的数组,不能创建新的数组。因为数组是有序的,相同的元素已经排在了一起,如果前后两个元素不同,那么我们就找到了一个新的元素。

滑动窗口

我么定义两个指针lr,右指针不断往后遍历找到与左指针不同的元素,找到以后左指针也往后走一步,然后进行交换

1. 初始化左指针和右指针

00001123
l,r

2. 右指针不断遍历找到不同的元素

00001123
lr

3. 左指针移动一位,准备放入下一个不同元素

00001123
lr

4. 把当前不同的元素放到前面

01001123
lr

5. 重复之前的逻辑

右指针不断移动找下一个不同的元素

01001123
lr

找到后左指针移动并填充

01201123
lr

右指针不断移动找下一个不同的元素

01001123
lr

找到后左指针移动并填充

01231123
lr

6.右指针到底末端结束

class Solution:def removeDuplicates(self, nums: List[int]) -> int:l = 0for r in range(len(nums)):if nums[l] != nums[r]:l += 1nums[l] = nums[r]return l+1

在这个问题中,我们可以破坏数组,所以可以直接将后面的元素覆盖到前面去

删除有序数组中的重复项 II

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

暴力解法

我们定义一个数组,不断添加元素,如果与这个数组尾端不同,则直接添加进来,如果与尾端相同,我们则判断添加的次数,超过2之后不在添加

class Solution:def removeDuplicates(self, nums: List[int]) -> int:tmp = []k = 1for i in range(len(nums)):# 如果为空则直接添加# 如果与末端元素不同也直接添加if not tmp or tmp[-1] != nums[i]:tmp.append(nums[i])k = 1# 如果与末端元素相同,则记录添加的次数k += 1# 小于2次则接着添加if k <= 2:tmp.append(nums[i])return tmp           

一个小小的优化是,其实我们不需要记录重复的次数,由于末端我们只会2个相同的元素,因此只需要比较tmp[-2]是否相同即可

temp[-3]temp[-2]temp[-1]nums[i]
前两个相同xxynums[i]!=tmpe[-2],说明中间只有一个y,可以直接添加
后两个相同xyy如果nums[i]==temp[-2],说明中间已经有一个y了,不能再添加了
全都不同xzynums[i]!=tmpe[-2],说明中间只有一个y,可以直接添加
class Solution:def removeDuplicates(self, nums: List[int]) -> int:if len(nums) <= 2:return numstmp = [nums[0],nums[1]]for i in range(2, len(nums)):# 如果为空则直接添加# 如果nums[i] != tmp[-2]说明末端元素只有一个,无脑添加if not tmp or tmp[-2] != nums[i]:tmp.append(nums[i])return tmp    

滑动窗口

数组是有序的,因此所有相同的元素肯定都是在一起出现的,同时要求一个元素最多出现两次,一个简单的想法就是
右指针不断移动,直到找到与左指针不同的元素,我们要把这个不同元素保留下来,即直接放到前面去(当前左指针后面)

000011123
lr

放到前面去

010011123
lr

由于重复元素需要保留2个,左指针需要再移动一位存放元素

010011123
lr

把重复的第2个值保留到前面

011011123
lr

当前这个元素已经满足要求了(不超过2个),右指针接着往后找下个不同的元素

011011123
lr

我们需要记录当前元素已经找到几个相同的了,如果小于等于2,那么左指针都需要跟着走,如果大于2了,左指针就不要动了,一直等找到下一个不同的元素

理清思路

好好理一下思路

  1. 右指针不断后移找到不同的元素
  2. 定义一个变量,记录当前的元素重复的次数
  3. 如果小于等于k,那么左指针移动,并将这个元素保留过来
  4. 如果重复次数超过了k,左指针不动,一直找到下一个重复元素,k重新赋值为1
class Solution:def removeDuplicates(self, nums: List[int]) -> int:if not nums:  # 处理空数组return 0l = 0k = 1  # nums[l] 初始出现1次# r从1开始,因为0位置已被l标记for r in range(1, len(nums)):if nums[l] == nums[r]:k += 1# 出现次数<=2时,扩展有效数组if k <= 2:l += 1nums[l] = nums[r]  # 这里漏了赋值,需要补充else:# 遇到新元素,重置计数并扩展有效数组k = 1l += 1nums[l] = nums[r]return l + 1

滑动窗口优化

因为数组是有序的,重复元素会连续排列。假设有效数组的最后两个元素是nums[l-2]和nums[l-1](当l >= 2时),此时:

  • 如果num == nums[l-2],说明nums[l-2]、nums[l-1]、num三者相等(因为数组有序,中间的nums[l-1]必然也等于num),加入num就会导致该元素出现 3 次,不符合要求。
  • 如果num != nums[l-2],说明即使num和nums[l-1]相等(最多出现 2 次),也不会超过限制,因此可以加入有效数组。
from typing import Listclass Solution:def removeDuplicates(self, nums: List[int]) -> int:l = 0  # 慢指针:指向有效数组的末尾for num in nums:# 核心判断:# 1. 有效数组长度不足2时,直接加入(前两个元素一定有效)# 2. 超过2个元素时,若当前元素与有效数组倒数第二个不同,说明可加入(避免3次重复)if l < 2 or num != nums[l-2]:nums[l] = numl += 1return l

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

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

相关文章

嵌入式学习---(单片机)

1.UART的概念通用异步收发器&#xff0c;2个串口&#xff08;1个串口被用于ISP下载程序&#xff0c;1个串口被用于和主机之间的通信&#xff09;&#xff0c;RXD(接收信号线) TXD(发送信号线)2、单工、半双工、全双工概念对比维度单工&#xff08;Simplex&#xff09;半双工&am…

基于单片机的宠物屋智能系统设计与实现(论文+源码)

1设计思路本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢&#xff0c;连接红外测温传感器&#xff0c;可实时精准捕捉宠物体温变化&#xff0c;以便及时发现健康异常&#xff1b;水位检测传感器时刻监测饮用水余量&#xff0c…

【面试】Java基础面试题

1. Java 基本数据类型有哪些&#xff1f;场景&#xff1a;面试官问「String 是不是基本类型&#xff1f;」答案要点&#xff1a;8 种基本类型&#xff1a;byte, short, int, long, float, double, char, boolean。String 是引用类型。追问链条&#xff1a;问&#xff1a;为什么…

PHP云课堂在线网课系统 多功能网校系统 在线教育系统源码

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 云课堂&#xff0c;依托腾讯云基础服务架构&#xff0c;采用C扩展框架Phalcon开发&#xff0c; 系统功能 实现了点播、直播、专栏、会员、积分、秒杀、微聊等。 友情提示&#xff1a;…

GEM5学习(4): 运行全系统模式的ARM系统

详细说明可以见官网 gem5: Extending gem5 for ARM 下载镜像 mkdir -p cpu_tests/benchmarks/bin/arm cd cpu_tests/benchmarks/bin/arm wget dist.gem5.org/dist/v22-0/test-progs/cpu-tests/bin/arm/Bubblesort wget dist.gem5.org/dist/v22-0/test-progs/cpu-tests/bin/arm…

快捷:常见ocr学术数据集预处理版本汇总(适配mmocr)

快捷&#xff1a;常见ocr学术数据集预处理版本汇总&#xff08;适配mmocr&#xff09;快捷&#xff1a;常见ocr学术数据集预处理版本汇总&#xff08;适配mmocr&#xff09;状态指标验证快捷&#xff1a;常见ocr学术数据集预处理版本汇总&#xff08;适配mmocr&#xff09; 状…

从抽象到实现:Elasticsearch数据类型及其底层Lucene数据结构的深度解析

第一部分&#xff1a;Lucene基础&#xff1a;核心索引结构Elasticsearch的强大功能根植于其核心——Apache Lucene&#xff0c;一个高性能、功能完备的搜索引擎库 1。要深入理解Elasticsearch如何处理各种数据类型&#xff0c;首先必须剖析构成Lucene索引的三个基本数据结构&am…

Claude Code核心功能操作指南

&#xff08;一&#xff09;核心交互面板&#xff1a;认识操作界面 登录后进入 Claude Code 主界面&#xff0c;核心区域分为三部分&#xff0c;各模块功能清晰&#xff1a;可以通过 注册免费体验。左侧导航栏&#xff1a;包含 “新建任务”“历史记录”“收藏夹”“帮助中心”…

数据仓库进化:Agent驱动数智化新范式

目录 回顾&#xff1a;从 "人为中心" 的数仓&#xff0c;到大数据与云数仓的进化 AI Agent 成为数据的 "新用户" Agentic Data Stack 如何打破低效与内耗 企业数智化的新范式 案例与趋势展望 所有软件都会被 Agent 改写一遍 经过半个世纪的数据仓库发…

什么是shellcode

好的&#xff0c;我们来详细地解释一下什么是 Shellcode。核心定义Shellcode 是一段精炼的、用作有效载荷&#xff08;Payload&#xff09; 的机器代码。它之所以叫这个名字&#xff0c;是因为最初这类代码的唯一目的就是启动一个命令行 Shell&#xff08;例如 /bin/sh&#xf…

线性代数 | 行图像 / 列图像

注&#xff1a;本文为 “线性代数 | 行图像 / 列图像” 相关合辑。 图片清晰度受引文原图所限。 略作重排&#xff0c;未整理去重。 如有内容异常&#xff0c;请看原文。 MIT 线性代数笔记一 行图像和列图像 线性代数行图像与列图像解析 herosunly 已于 2022-01-25 15:34:26 …

Batch Normalization:深度学习中的“加速器”与“稳定器”

在深度学习的世界里&#xff0c;神经网络的训练常常充满了挑战。从复杂的梯度问题到漫长的收敛过程&#xff0c;每一个环节都可能成为阻碍我们前进的绊脚石。而今天&#xff0c;我们要深入探讨的 BatchNormalizationBatch NormalizationBatchNormalization&#xff08;批量归一…

软考备考①

一、数值及其转换和数据的表示1、数值及其转换①任意进制到十进制以二进制为例&#xff0c;以小数点做分割&#xff0c;小数点以左从二的零次方开始&#xff0c;小数点以右从二的负一次方开始。②十进制到任意进制利用短除法③二进制到十六进制分为小数点前和小数点后&#xff…

小程序缓存数据字典

import { getDict } from /api/profile;const CACHE_KEY DICT_CACHE;let dictCache new Map();// 初始化时加载缓存const loadCache () > {const cache uni.getStorageSync(CACHE_KEY);if (cache) {dictCache new Map(JSON.parse(cache));}};// 保存缓存到Storageconst…

Java对象在内存中的布局详解

1、Java 对象内存布局&#xff08;HotSpot 虚拟机&#xff09;在 ​HotSpot 虚拟机​ 中&#xff0c;一个 Java 对象在堆内存中的存储布局可以分为以下几个部分&#xff1a;1、对象头&#xff08;Object Header&#xff09;​对象头是对象内存布局中最重要的部分之一&#xff0…

钾元素:从基础认知到多元应用与前沿探索

一、钾元素的基础认知1.1 钾元素的发现历程在人类历史的长河中&#xff0c;钾的化合物早早就进入了人们的视野&#xff0c;并在生活和生产中得到了应用。古代时期&#xff0c;人们就知晓草木灰里含有钾草碱&#xff0c;即碳酸钾 。在日常的洗涤活动中&#xff0c;碳酸钾发挥了重…

JAiRouter 配置文件重构纪实 ——基于单一职责原则的模块化拆分与内聚性提升

JAiRouter 配置文件重构纪实 ——基于单一职责原则的模块化拆分与内聚性提升 文章目录JAiRouter 配置文件重构纪实 ——基于单一职责原则的模块化拆分与内聚性提升一、背景&#xff1a;单体 YAML 的“熵增”困境二、重构策略&#xff1a;高内聚、低耦合的模块化方案2.1 拆分原则…

惊!printf 不往屏幕输?都是 fd 在搞鬼!爆肝拆解 Linux 文件描述符 + 重定向底层,学会直接在终端横着走

文 章 目 录一、文 件1、基 础 知 识2、C 文 件 接 口&#xff08;1&#xff09;代 码 示 例&#xff08;2&#xff09;当 前 路 径&#xff08;3&#xff09;文 件 权 限&#xff08;4&#xff09;w&#xff08;5&#xff09;a&#xff08;6&#xff09;三 个 输 入 输 出 流3…

【高分论文密码】大尺度空间模拟与不确定性分析及数字制图技术应用

大尺度模拟技术能够从不同的时空尺度揭示农业生态环境领域的内在机理和时空变化规律&#xff0c;为复杂过程模型的模拟提供技术基础。一&#xff1a;R语言空间数据及数据挖掘关键技术1、R语言空间数据讲解及应用特点 1)R语言基础与数据科学 2)R空间矢量数据 3)R栅格数据2、R语言…

Git 工作流与分支管理实战:rebase vs merge 对比、冲突解决、规范 Commit Message 与主干稳定性最佳实践

1. 版本控制与协作流程&#xff08;Git 工作流、分支管理、合并冲突&#xff09; 虽然 Git 用得多&#xff0c;但“rebase vs. merge”、如何解决冲突、如何编写规范的 commit message、如何维护主干的稳定性&#xff0c;都需要一段时间才能形成体系化的理解。 摘要 在日常团队…