我愛學算法之——滑動窗口攻克子數組和子串難題(上)

現在來學習"滑動窗口"這一算法思想。

至于什么是"滑動窗口"呢?簡單來說就是同向雙指針;現在來通過題目來了解什么是"滑動窗口"

一、長度最小的子數組

題目鏈接:長度最小的子數組

題目解析

在這里插入圖片描述

先來看題目,給了一個數組nums和一個整數target,讓我們找到nums的一個滿足條件(條件:子數組的和大于target)的最長子數組。

算法思路

首先第一次看到子數組/子串問題的算法題,能想到的思路就肯定是暴力枚舉了;現在就先來看暴力枚舉如何解決的。

暴力枚舉

我們依次枚舉整個數組的每一個子數組,并判斷是否滿足條件;滿足條件且長度小于最總結果,就更新最終結果。

上面意思呢?

在這里插入圖片描述

暴力解法的大致思路如上述所示;現在來看一下暴力枚舉有哪些操作是不必要的

  • right第一次找到滿足條件的位置并更新結果后,left++rightleft位置再重新遍歷

這個操作感覺有些多余了,因為我們right遍歷時第一次遇到滿足條件的就停了下來;

如果rightleft++后的位置開始再遍歷到上次滿足條件位置的位置,這一個遍歷過程很多余;

什么意思呢?

就以暴力枚舉中的示例來說:

right第一次遍歷到下標為3位置恰好滿足條件;此時區間是[0,3],我們更新結果之后,left++

right從下標為1的位置開始再次遍歷;

我們直到[0,3]區間剛滿足條件,那區間[1,1][1,2]是一定不滿足條件的[1,3]才有可能滿足條件。

那這樣我們就可以想辦法省略這個不必要的步驟:

找到滿足條件的區間,并更新結果并lef++后,如何去解決right重新遍歷的問題?

解決問題,我們要找到問題的本質

**暴力枚舉**中為什么要重新進行遍歷,本質問題就是我們不知道left++后,區間[left,right]的和;(所以暴力枚舉才會進行重新遍歷)

那我們現在定義一個變量sum來實時記錄區間[left,right]的和,這樣不就不需要重新遍歷了嗎。

我們只需要在right向后遍歷和left更新時,順手更新一下sum的值就可以了。

滑動窗口

其實滑動窗口就是優化了暴力枚舉解法中不必要的部分

知道了如何去解決暴力枚舉中不必要的問題,現在來實現

在這里插入圖片描述

通過上圖所示推到,我們的想法是可行的,現在來看整體的一個思路

滑動窗口,為什么稱為滑動窗口?

就是rightleft在遍歷更新的過程中維護了一段區間[left , right],這個區間像窗口一樣在數組中滑動。

現在來看實現這個問題的一個整體思路:

  • 進窗口:讓right向右遍歷,更新區間[left , right]的和sum;稱為進窗口(就是讓right遍歷到的元素進入(窗口)區間內。
  • 出窗口:如果當前區間滿足條件(區間大于target),就更新結果,然后讓left++,并更新區間[left , right]的和;重復上述操作直到區間不滿足條件。
  • 更新結果:至于什么時候更新結果,每一道題都不一樣,根據題目中的要求再決定什么時候更新結果。

代碼實現

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size();int ret = n+1;int l=0,r=0;int sum =0;while(l<n){//進窗口sum += nums[l++];//出窗口while(sum>=target){int x= l-r;if(x < ret)ret = x;sum-=nums[r++];}}if(ret == n+1)return 0;return ret;}
};

二、無重復字符的最長子串

題目鏈接:無重復字符的最長子串

題目解析

在這里插入圖片描述

題目要求找出來給定字符串的所有子串中,不包含重復字符的最長子串;(也是子串問題)

  • s字符串中的字符由英文字母、數字、符號和空格組成。

算法思路

這里首先還是來看暴力解法

枚舉出來所有不包含重復字符的子串

在其中找到最長的然后返回。

這里先來看一下如何處理重復字符的問題:

這里可以使用一個hash表,其中記錄每一個字符出現的次數;

這樣使用leftright雙指針遍歷的時候,遍歷到hash[s[right]] > 1就代表當前區間內存在重復字符。

當然這里所有數組來模擬hash就可以了

現在來看使用滑動窗口如何去解決。

進窗口:首先right向右遍歷,遍歷過程中hash[s[right]]++更新當前字符出現的次數;

出窗口:當hash[s[right]] >1時就表示當前區間不滿足條件,就要left++并且hash[s[left]]--更新區間內字符出現的字符;直到hash[s[right]]<=1

更新結果:這里每一次出完窗口就表示找到了一個滿足條件的區間,所以出完窗口之后更新結果即可。(這里在right剛開始遍歷,每一次出完窗口,不一定會進入出窗口,但是也會更新結果,不會遺漏)。

代碼實現

這里寫代碼時注意,我們數組模擬hash,數組大概開辟128就差不多夠了。

class Solution {
public:int lengthOfLongestSubstring(string s) {int hash[128]={0};int n = s.size();int left = 0, right = 0;int ret = 0;while(right < n){//進窗口hash[s[right]]++;while(hash[s[right]]>1)hash[s[left++]]--;ret = max(ret,right-left+1);right++;}return ret;}
};

三、最大連續1的個數 III

題目鏈接:最大連續1的個數 III

題目解析

在這里插入圖片描述

題目給定一個數組nums,和k;其中nums中每一個數字不是1就是0

k表示最多可以反轉(01)的次數。

要求我們返回操作之后,數組中連續1的最大個數。

什么意思呢?

就是我們最多可以將k個數組中的0變成1,然后我們要找出進行變換操作后數組中連續1的最大個數。

算法思路

這里,做出來本道題的關鍵就在于如何處理這個最多k01的問題。

這里我們真的要將0變成1?

顯然是不可以的,這里數組有很多子數組,變了之后如何接著進行呢?

所以我們不能這樣操作,就只能另辟蹊徑:

這道題也是最長子數組問題,那也是要用滑動窗口的;我們想一想如何將其變成這樣的問題?

很顯然,這里題目要求最多可以進行k次變換,我們不能進行真的變化操作。

就只能在原數組中找到一個子數組(其中0的個數不超過k);

這樣這個問題就變成了我們熟悉的找子數組的問題,這里條件就是區間內0的個數不超過k

所以思路就簡單明了了。

這里定義一個變量zero來記錄區間[left , right]0的個數。

入窗口:right向右遍歷,遇到0就更新zero

出窗口:如果zero>k就表示當前區間內不滿足條件了,就進行出窗口操作;如果nums[left] == 0,就更新zero

更新結果:這里更新結果還是在出窗口之后,出窗口之后區間是滿足條件的并且每次入窗口之后不一定會出窗口,這樣更新就不會漏掉每一種情況。

代碼實現

class Solution {
public:int longestOnes(vector<int>& nums, int k) {int n = nums.size();int left = 0, right =0;int zero = 0;int ret = 0;while(right<n){//入窗口if(nums[right++] == 0)zero++;//出窗口while(zero>k){if(nums[left++]==0)zero--;}//更新結果ret = max(ret,right - left);}return ret;}
};

這里第一次接觸到滑動窗口,感覺有一點點抽象;

這里滑動窗口其實就是同向雙指針,只是在遍歷的過程中維護了一段區間就像一個窗口一樣在數組中滑動。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/72632.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72632.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72632.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ora-600 ktugct: corruption detected---惜分飛

接手一個oracle 21c的庫恢復請求,通過Oracle數據庫異常恢復檢查腳本(Oracle Database Recovery Check)腳本檢測之后,發現undo文件offline之后,做了resetlogs操作,導致該文件目前處于WRONG RESETLOGS狀態 嘗試恢復數據庫ORA-16433錯誤 SQL> recover datafile 1; ORA-00283:…

20. Excel 自動化:Excel 對象模型

一 Excel 對象模型是什么 Excel對象模型是Excel圖形用戶界面的層次結構表示&#xff0c;它允許開發者通過編程來操作Excel的各種組件&#xff0c;如工作簿、工作表、單元格等。 xlwings 是一個Python庫&#xff0c;它允許Python腳本與Excel進行交互。與一些其他Python庫&#x…

IIS 服務器日志和性能監控

Internet Information Services &#xff08;IIS&#xff09; 是 Microsoft 提供的一款功能強大、靈活且可擴展的 Web 服務器&#xff0c;用于托管網站、服務和應用程序。IIS 支持 HTTP、HTTPS、FTP、SMTP 和更多用于提供網頁的協議&#xff0c;因此廣泛用于企業環境。 IIS 的…

jenkins pipline 自動化測試

以下是一個典型的 Jenkins Pipeline 示例&#xff0c;用于執行自動化測試流程&#xff08;支持單元測試、集成測試、代碼質量掃描&#xff09;&#xff0c;包含多階段執行和測試結果處理&#xff1a; pipeline {agent anyenvironment {// 定義環境變量PROJECT_NAME "my-…

APP測試

一、APP測試范圍 功能測試性能測試&#xff1a;CPU、內存占用、啟動速度、流量、電量消耗、流暢度、穩定性專項測試&#xff1a;安裝卸載升級、push消息推送 、交叉事件測試 、用戶體驗測試 、兼容性測試 二、APP包發布方式及策略 分類&#xff1a; 內部發布渠道。如&#x…

12 File文件對象:創建、獲取基本信息、遍歷文件夾、查找文件;字符集的編解碼 (黑馬Java視頻筆記)

文章目錄 File >> 存儲數據的方案1. 認識File2. File操作2.1 創建File對象2.2 File操作1&#xff09;對文件對象的信息的操作2&#xff09;文件/文件夾的創建/刪除3&#xff09;??對文件夾的遍歷 3. 方法遞歸3.1 認識遞歸3.2 遞歸算法及其執行流程1) 案例&#xff1a;2…

oracle 基礎知識之 多表查詢

多表查詢定義&#xff1a;當查詢的數據并不是來源一個表時&#xff0c;需要使用多表連接操作完成查詢。多表連接查詢通過表之間的關聯字段&#xff0c;一次查詢出多個表的數據。多表查詢包括了等值連接、左連接、右連接、完全連接。 1.等值連接 等值連接也稱為簡單連接&#xf…

服務器防火墻根據什么特征來過濾數據包?

防火墻是服務器安全防護的第一道屏障&#xff0c;它的主要作用是監控、過濾和控制進出服務器的數據流量&#xff0c;防止惡意攻擊、非法訪問和數據泄露。防火墻通過分析數據包的特定特征來決定是否允許、拒絕或限制數據的傳輸。 服務器防火墻的基本工作原理&#xff1a; 防火墻…

Prims region.Views 為null

原因&#xff1a; 導航未完成或異步問題 解決方式&#xff1a;使用回調確認導航完成后再操作視圖 _regionManager.RequestNavigate("MonitorRegion", "MonitorView", nps, navigationResult > {if (navigationResult.Result true){var region _regio…

reconstruct_3d_object_model_for_matching例子

文章目錄 1.獲取om3文件2.準備可視化3.準備3D可視化4.讀取3D模型5.顯示成對注冊結果16.顯示成對注冊結果27.聯合注冊模型8.處理圖像8.1子采樣8.2 圖像計算與平滑8.3 三角測量 9.基于表面做3D匹配10.評估模型準確度10.1 在場景中找到模型10.2 計算模型和場景之間的距離 11.立體系…

軟件安全性測試的重要性和常用工具介紹,軟件測試服務公司推薦

在當今數字化快速發展的時代&#xff0c;軟件已經成為各行各業不可或缺的一部分。然而&#xff0c;隨著軟件系統的復雜性增加&#xff0c;安全性問題也愈發突出&#xff0c;因此軟件產品生產周期中安全測試必不可少。軟件安全性測試是指對軟件系統進行評估&#xff0c;以發現潛…

Redis項目:短信驗證碼登錄

這是黑馬的黑馬點評項目&#xff0c;短信驗證碼的業務。一開始是使用session做的&#xff0c;后來重構&#xff0c;使用redis緩存來完成。 第一層攔截器&#xff1a; public class RefreshTokenInterceptor implements HandlerInterceptor {private StringRedisTemplate stri…

Docker下載,包含Win、Mac

介紹 Docker 是一種開源的容器化平臺&#xff0c;通過操作系統級虛擬化技術實現應用的快速開發、部署和運行。以下從多個維度對 Docker 進行詳細介紹&#xff1a; 一、Docker 的核心概念與功能 容器化技術 Docker 利用 Linux 內核的容器隔離技術&#xff08;如 Cgroups 和 Nam…

使用 ESP8266 和 Android 應用程序實現基于 IOT 的語音控制家庭自動化

使用 ESP8266 實現基于 IOT 的語音控制家庭自動化 歡迎來到另一個令人興奮的項目,我們將使用 Wi-Fi 模塊構建一個語音控制ESP8266家庭自動化系統,您可以在其中通過語音通過 Android 應用程序從世界任何地方控制您的家用電器。是的,您只需使用語音命令即可打開或關閉負載(L…

【HarmonyOS Next】鴻蒙中自定義彈框OpenCustomDialog、CustomDialog與DialogHub的區別詳解

【HarmonyOS Next】鴻蒙中自定義彈框OpenCustomDialog、CustomDialog與DialogHub的區別詳解 一、三者的區別與關系 1. 官方迭代過程為&#xff1a; CustomDialog 》 OpenCustomDialog 》 DialogHub 迭代過程表明&#xff0c;彈框的調用越來越便捷&#xff0c;與UI解耦&…

【C++】stack和queue的使用及模擬實現(含deque的簡單介紹)

文章目錄 前言一、deque的簡單介紹1.引入deque的初衷2.deque的結構3.為什么選擇deque作為stack和queue的底層默認容器 二、stack1.stack的介紹2.stack的使用3.stack的模擬實現 三、queue1.queue的介紹2.queue的使用3.queue的模擬實現 前言 一、deque的簡單介紹&#xff08;引入…

Leetcode 刷題筆記1 圖論part01

圖論的基礎知識&#xff1a; 圖的種類&#xff1a; 有向圖&#xff08;邊有方向&#xff09; 、 無向圖&#xff08;邊無方向&#xff09;、加權有向圖&#xff08;邊有方向和權值&#xff09; 度&#xff1a; 無向圖中幾條邊連接該節點&#xff0c;該節點就有幾度&#xff1…

《基于Workspace.java的Launcher3改造:HotSeat區域動態阻斷文件夾生成機制》

1. 需求背景與技術挑戰 在Android 13系統Launcher3定制化開發中&#xff0c;需實現禁止HotSeat區域創建文件夾的功能。原始邏輯中&#xff0c;當用戶拖拽應用圖標至HotSeat區域相鄰圖標時&#xff0c;會觸發FolderIcon的實例化。本文將深入分析Launcher3的文件夾創建機制&…

重生之我在學Vue--第14天 Vue 3 國際化(i18n)實戰指南

重生之我在學Vue–第14天 Vue 3 國際化(i18n)實戰指南 文章目錄 重生之我在學Vue--第14天 Vue 3 國際化(i18n)實戰指南前言一、Vue I18n 核心配置1.1 基礎環境搭建1.2 初始化配置1.3 全局掛載 二、多語言實現方案2.1 基礎使用2.2 動態切換語言2.3 高級功能實現復數處理日期/貨幣…

開源PACS(dcm4che-arc-light)部署教程,源碼方式

目錄 文件清單下載地址安裝概述OpenLDAP、Apache Directory StudioWildflydcm4che 安裝部署MySQL源碼編譯dcm4cheedcm4chee-arc-light OpenLDAP安裝ApacheDirectoryStudio安裝配置WildFly服務器 部署完成 文件清單 下載地址 Apache directory studio - linkOpenLDAP - linkdcm…