動態維護有效區間:滑動窗口

右指針不斷移動獲取解,左指針不斷移動縮小解范圍

左指針的意義非常重要,相當于一個標兵,不斷與這個標兵進行比較,如果符合要求,這左指針進行移動,并進行操作,如果不符合要求,則左指針不動,右指針接著尋找符合要求的值。

刪除有序數組中的重復項

給你一個 非嚴格遞增排列 的數組 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
英文地址,請注明出處:http://en.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;都需要一段時間才能形成體系化的理解。 摘要 在日常團隊…