leetcode 滑動窗口小結 (一)

目錄

  • 小結以及代碼框架
  • 76. 最小覆蓋子串
    • 滑動窗口
    • 代碼以及注釋
  • 567. 字符串的排列
    • 滑動窗口
  • 438. 找到字符串中所有字母異位詞
  • 3. 無重復字符的最長子串
    • 化簡框架
  • reference

小結以及代碼框架

滑動窗口技巧屬于雙指針技巧。
該算法的思路為維護一個窗口,不斷滑動,然后更新答案。
大致框架如下:[參考labuladong的算法小抄]

int left = 0, right = 0;while(right < s.size())
{//增大窗口window.add(s[right]);right++;while(window needs shrink){//縮小窗口window.remove(s[left]);left++;}
}

主要的細節問題:
1、如何向窗口中添加新元素
2、如何縮小窗口
3、在窗口滑動的哪個階段更新結果

//滑動窗口算法框架
void slidingWindow(string s, string t)
{unordered_map<char,int> need, window;for(char c : t) need[c]++;int left = 0, right = 0;int valid = 0;while(right < s.size()){//c是將要移入窗口的元素char c  = s[right];//右移窗口right++;//進行窗口內數據更新(右移窗口)/*******************//**debug輸出位置***/cout << "window:[ "<<left << " , " << right <<"]"<<endl;/******************///判斷左側窗口是否需要收縮while(window needs shrink){//d是將移出窗口的字符char d = s[left];//左移窗口left++;//進行窗口內數據的一系列更新(左移窗口)}}
}

76. 最小覆蓋子串

https://leetcode-cn.com/problems/minimum-window-substring/
給你一個字符串 s 、一個字符串 t 。返回 s 中涵蓋 t 所有字符的最小子串。如果 s 中不存在涵蓋 t 所有字符的子串,則返回空字符串 “” 。

注意:如果 s 中存在這樣的子串,我們保證它是唯一的答案。
示例 1:

輸入:s = “ADOBECODEBANC”, t = “ABC”
輸出:“BANC”

示例 2:

輸入:s = “a”, t = “a”
輸出:“a”

提示:
1 <= s.length, t.length <= 10^5
s 和 t 由英文字母組成

滑動窗口

1、初始化window和need兩個哈希表,記錄下窗口中的字符以及需要湊齊的字符:

unordered_map<char,int> need,window;
for(char c : t) need[c]++;

2、使用left和right變量初始化窗口兩端,區間是左閉右開,初始情況下,窗口內是沒有元素的。

int left = 0, right = 0;
while(right < s.size())
{//開始滑動
}

3、定義記錄變量
valid_length表示window內滿足need條件的字符個數,如果valid_length == need.size() 說明窗口已經滿足了條件,已經完全覆蓋了串T。

int valid_length;

在right向右擴充的時候,對新進來的元素進行檢查,如果它是need中的元素,window中對應這個元素就要+1,然后判斷window中這個元素的個數是不是need中這個元素的個數相同,如果相同說明這個元素在window中已經找完了,這時候就需要將valid_length+1了
4、套用模板
確定四個問題的具體細節:
1、當right移動,擴大window,應該更新哪些數據?

更新window計數器

2、當left移動,縮小window,應該更新哪些數據?

更新window計數器

3、什么條件下暫停擴大window,開始移動left縮小window?

當valid長度等于need大小時,應該收縮窗口

4、結果應該在擴大窗口時還是縮小窗口時進行?

縮小窗口的時候進行更新結果

代碼以及注釋

class Solution {
public:string minWindow(string s, string t) {unordered_map<char,int> window,need;//記錄下t中有哪些元素以及每個元素的個數for(char c : t) need[c]++;//初始化窗口邊界int right = 0, left = 0;//window滿足need條件的元素個數int valid_length = 0;//結果字符串在s中的起始地址以及長度,這樣就不要每次更新整個string了int start = 0 , length = INT_MAX;while(right < s.size()){//******************擴充窗口**************//擴充窗口right++;//擴充進來的新元素char c = s[right - 1]; //判斷該元素是否是need中元素if(need.count(c)){window[c]++;if(window[c] == need[c]) valid_length++;}//*******************縮小窗口*************//如果need中所有元素都在window內,并且每個元素的頻數也與window內元素頻數相同,那么此時就得到了一個答案,記錄答案,然后縮小窗口,以獲得更優的答案while(valid_length == need.size()){//如果此次答案比上次的答案長度要小,我們才更新答案if(right - left < length){start = left;length = right - left;}//左邊界向左移動left++;//d是剛移出窗口的元素char d = s[left - 1];//如果need中出現了dif(need.count(d)){//如果之前d元素在window和need出現的頻數相同if(window[d] == need[d]){//刪除了之后,頻數不相同了,所以這個元素也就不滿足了。valid_length--;}window[d]--;}}}//如果length沒有更新,說明s不存在t中字符或者不滿足字符頻數,返回空字符串,否則,使用substr將子串返回return length == INT_MAX ? "" : s.substr(start,length);}
};

567. 字符串的排列

https://leetcode-cn.com/problems/permutation-in-string/
給定兩個字符串 s1 和 s2,寫一個函數來判斷 s2 是否包含 s1 的排列。

換句話說,第一個字符串的排列之一是第二個字符串的子串。

示例1:

輸入: s1 = “ab” s2 = “eidbaooo”
輸出: True
解釋: s2 包含 s1 的排列之一 (“ba”).

示例2:

輸入: s1= “ab” s2 = “eidboaoo”
輸出: False

注意:

輸入的字符串只包含小寫字母
兩個字符串的長度都在 [1, 10,000] 之間

滑動窗口

精確化題目為:假設給你一個S和T,請問S中是否存在一個子串,包含T中所有字符且不包含其他字符
精確化本題細節:
1、移動left縮小窗口的時機:窗口大小大于t的大小,因為各種排列的長度應該是一樣的。
2、當valid_length == need.size()時,說明窗口中的數據是一個合法的數據,應該立即返回true;

class Solution {
public:bool checkInclusion(string s1, string s2) {unordered_map<char,int> window,need;for(char c : s1) need[c]++;int left = 0,right = 0;int valid_length = 0;while(right < s2.size()){//擴充windowright++;char c = s2[right - 1];if(need.count(c)){window[c]++;if(window[c] == need[c]) valid_length++;}//縮小windowwhile(right - left >= s1.size()){if(valid_length == need.size()) return true;left++;char d = s2[left - 1];if(need.count(d)){if(window[d] == need[d]) valid_length--;window[d]--;}}}return false;}
};

438. 找到字符串中所有字母異位詞

https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/
給定一個字符串 s 和一個非空字符串 p,找到 s 中所有是 p 的字母異位詞的子串,返回這些子串的起始索引。

字符串只包含小寫英文字母,并且字符串 s 和 p 的長度都不超過 20100。

說明:
字母異位詞指字母相同,但排列不同的字符串。
不考慮答案輸出的順序。
示例 1:

輸入:
s: “cbaebabacd” p: “abc”
輸出:
[0, 6]
解釋:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的字母異位詞。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的字母異位詞。

** 示例 2:**

輸入:
s: “abab” p: “ab”
輸出:
[0, 1, 2]
解釋:
起始索引等于 0 的子串是 “ab”, 它是 “ab” 的字母異位詞。
起始索引等于 1 的子串是 “ba”, 它是 “ab” 的字母異位詞。
起始索引等于 2 的子串是 “ab”, 它是 “ab” 的字母異位詞。

直接套模板

class Solution {
public:vector<int> findAnagrams(string s, string p) {if(s.empty()) return {};vector<int> result;unordered_map<char,int> need,window;for(char c : p) need[c]++;int left = 0,right = 0;int valid_length = 0;while(right < s.size()){//expand windowright++;char c = s[right - 1];if(need.count(c)){window[c]++;if(window[c] == need[c]){valid_length++;}}//shrink windowwhile(right - left >= p.size()){if(valid_length == need.size()){result.emplace_back(left);}left++;char d = s[left - 1];if(need.count(d)){if(window[d] == need[d]){valid_length--;}window[d]--;}}}return result;}
};

3. 無重復字符的最長子串

之前做過,這次用滑動窗口模板做:
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
給定一個字符串,請你找出其中不含有重復字符的 最長子串 的長度。
示例 1:

輸入: s = “abcabcbb”
輸出: 3
解釋: 因為無重復字符的最長子串是 “abc”,所以其長度為 3。

示例 2:

輸入: s = “bbbbb”
輸出: 1
解釋: 因為無重復字符的最長子串是 “b”,所以其長度為 1。

示例 3:

輸入: s = “pwwkew”
輸出: 3
解釋: 因為無重復字符的最長子串是 “wke”,所以其長度為 3。
請注意,你的答案必須是 子串 的長度,“pwke” 是一個子序列,不是子串。

示例 4:

輸入: s = “”
輸出: 0

提示:

0 <= s.length <= 5 * 10^4
s 由英文字母、數字、符號和空格組成.

化簡框架

將need、valid去除,更新窗口數據只需要更新window計數器。
當window[c]大于1,說明窗口內存在重復字符,不符合條件,就應該移動left縮小窗口。
對于更新結果:更新結果的操作放在收縮窗口之后,因為收縮之后窗口不存在重復字符。

class Solution {
public:int lengthOfLongestSubstring(string s) {if(s.empty()) return 0;int res = 0;unordered_map<char,int> window;int left = 0, right = 0;while(right < s.size()){//expand windowright++;char c = s[right -1];window[c]++;//如果進入窗口的新元素在窗口內有重復元素,就需要移動left//shrink windowwhile(window[c] > 1){left++;window[s[left - 1]]--;}res = max(res,right - left);}return res;}
};

reference

《labuladong的算法小抄》

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

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

相關文章

linux命令行界面_Linux中的命令行界面

linux命令行界面If you are like most people, you are probably most familiar with using a Graphical User Interface (GUI) to control your computer. Introduced to the masses by Apple on the Macintosh computer and popularized by Microsoft, a GUI provides an eas…

一道小小面試題的細節分析

一道小小面試題的細節分析 今天突然想到以前遇到的一個問題&#xff0c;題目如下&#xff08;可能絕大多數人都遇到過&#xff09;&#xff1a; 1 class A2 {3 public A()4 {5 PrintFields();6 }7 public virtual void Pr…

十四、OPTIM

一、torch.optim torch.optim.Optimizer(params, defaults)優化器官網說明 由官網給的使用說明打開看出來優化器實驗步驟&#xff1a; ①構造選擇優化器 例如采用隨機梯度下降優化器SGD torch.optim.SGD(beyond.parameters(),lr0.01)&#xff0c;放入beyond模型的參數param…

Windows下運行jekyll,編碼已不再是問題

很久沒更新jekyll了&#xff0c;所以好奇著去官網看了下更新記錄&#xff0c;發現如下更新條目&#xff08;版本1.3.0/2013-11-04發布&#xff09;&#xff1a; Add encoding configuration option (#1449)之前在windows下安裝jekyll運行編寫的代碼時&#xff0c;如果有中文&am…

leetcode 滑動窗口小結 (二)

目錄424. 替換后的最長重復字符思考分析1優化1004. 最大連續1的個數 III友情提醒方法1&#xff0c;基于當前最大頻數方法2&#xff0c;基于歷史最大頻數424. 替換后的最長重復字符 https://leetcode-cn.com/problems/longest-repeating-character-replacement/ 給你一個僅由大…

軟件故障_一些主要的軟件故障

軟件故障The need for software engineering was realized by the software industry after some of its major failures. Some of these failures are listed below, 在經歷了一些重大失敗之后&#xff0c;軟件行業意識到了對軟件工程的需求 。 下面列出了其中一些故障&#x…

十五、修改VGG16網絡來適應自己的需求

一、VGG-16 VGG-16神經網絡是所訓練的數據集為ImageNet ImageNet數據集中驗證集和測試集一萬五千張&#xff0c;有一千個類別 二、加載VGG-16神經網絡模型 VGG16模型使用說明 torchvision.models.vgg16(pretrainedFalse) 其中參數pretrained表示是否下載已經通過ImageNet數…

leetcode 滑動窗口小結 (三)

目錄978. 最長湍流子數組題目思路分析以及代碼1052. 愛生氣的書店老板題目思考分析與初步代碼優化思路以及優化代碼1208. 盡可能使字符串相等題目思考分析以及代碼978. 最長湍流子數組 https://leetcode-cn.com/problems/longest-turbulent-subarray/ 題目 當 A 的子數組 A[…

JAVA多線程學習3--線程一些方法

一、通過sleep方法睡眠 在指定的毫秒數內讓當前正在執行的線程休眠&#xff08;暫停執行&#xff09;。該線程不丟失任何監視器的所屬權。 二、線程優先級 線程具有優先級&#xff0c;范圍為1-10。 MAX_PRIORITY線程可以具有的最高優先級。int類型&#xff0c;值為10. MIN_PRIO…

mcq 隊列_MCQ | 量子密碼學

mcq 隊列1) Which possible Attacks in Quantum Cryptography can take place? 1)量子密碼術中可能發生哪些攻擊&#xff1f; Possible Attacks in Quantum Cryptography and Birthday Attack 量子密碼術和生日攻擊的可能攻擊 Birthday attack and Boomerang attack 生日襲擊…

《inside the c++ object model》讀書筆記 之一:對象

關于對象 ...引子:在C語言中,"數據"和"處理數據的操作(函數)"是分開來聲明的,語言本身并沒有支持"數據和函數"之間關聯性,這種程序成為"程序性的",由一組"分布在各個一功能為向導的函數中"的算法驅動,他們處理的是共同的外部…

十六、保存和加載自己所搭建的網絡模型

一、保存自己搭建的模型方法一 例如&#xff1a;基于VGG16網絡模型架構的基礎上加上了一層線性層&#xff0c;最后的輸出為10類 torch.save(objmodule,f"path")&#xff0c;傳入需要保存的模型名稱以及要保存的路徑位置 保存模型結構和模型的參數&#xff0c;保存文…

uC/OS-II OS_TASK.C中有關任務管理的函數

函數大致用途 OS_TASK.C是uC/OS-II有關任務管理的文件&#xff0c;它定義了一些函數&#xff1a;建立任務、刪除任務、改變任務的優先級、掛起和恢復任務&#xff0c;以及獲取有關任務的信息。 函數用途OSTaskCreate()建立任務OSTaskCreateExt()擴展建立任務OSTaskStkChk()堆…

windows下寫的腳本,在linux下執行失敗

Windows中的換行符為CRLF, 即正則表達式的rn(ASCII碼為13和10), 而Unix(或Linux)換行符為LF, 即正則表達式的n. 在Windows和Linux下協同工作的時候, 往往這個細小的差別就導致問題, 如 1)Windows下寫的Shell腳本, 在Linux下運行時往往出現rn是無效參數, 不能執行; 2)vi 等編器下…

Scala中的do ... while循環

做...在Scala循環 (do...while loop in Scala) do...while loop in Scala is used to run a block of code multiple numbers of time. The number of executions is defined by an exit condition. If this condition is TRUE the code will run otherwise it runs the first …

十七、完整神經網絡模型訓練步驟

以CIFAR-10數據集為例&#xff0c;訓練自己搭建的神經網絡模型架構 一、準備CIFAR-10數據集 CIFAR10官網使用文檔 torchvision.datasets.CIFAR10(root"./CIFAR_10",trainTrue,downloadTrue) 參數描述root字符串&#xff0c;指明要下載到的位置&#xff0c;或已有數…

μC/OS-Ⅱ 操作系統內核知識

目錄μC/OS-Ⅱ任務調度1.任務控制塊2.任務管理3.任務狀態μC/OS-Ⅱ時間管理μC/OS-Ⅱ內存管理內存控制塊MCBμC/OS-Ⅱ任務通信1.事件2.事件控制塊ECB3.信號量4.郵箱5.消息隊列操作系統內核&#xff1a;在多任務系統中&#xff0c;提供任務調度與切換、中斷服務 操作系統內核為每…

第二版tapout

先說說上次流回來的芯片的測試情況。 4月23日&#xff0c; 芯片采用裸片直接切片&#xff0c; bond在板子上&#xff0c;外面加了一個小塑料殼來保護&#xff0c;我們就直接拿回來測試了。 測試的主要分為模擬和數字兩部分&#xff0c; 數字部分的模塊基本都工作正常&#xff0…

cd-rom門鎖定什么意思_CD-ROM的完整形式是什么?

cd-rom門鎖定什么意思CD-ROM&#xff1a;光盤只讀存儲器 (CD-ROM: Compact Disc Read-Only Memory) CD-ROM is an abbreviation of "Compact Disc Read-Only Memory". It is a data storage memory in the form of an optical compact disc, which is read by a syst…

遠程工作時的協作工具

遠程工作時的協作工具 Google Hangout 用于日常會議和面對面交談,在國內其實可以用qq來帶起。Campfire 用于一天來的持續對話。Screenhero 用于分享屏幕&#xff0c;一起寫代碼,這個比較有用,可以一起寫代碼。Balsamiq 用于計劃要制作的 UI。Asana 用于管理任務Google Docs 用于…