算法學習筆記:雙指針_滑動窗口專題

目錄

1.長度最小的子數組

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

3.將x減少到0的最小操作數

4.最大連續1的個數Ⅲ

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

6.水果成籃

7.串聯所有單詞的子串

8.最小覆蓋子串

1.長度最小的子數組:209. 長度最小的子數組 - 力扣(LeetCode)中等

2.無重復字符的最長子串:3. 無重復字符的最長子串 - 力扣(LeetCode)中等

3.將x減少到0的最小操作數:1658. 將 x 減到 0 的最小操作數 - 力扣(LeetCode)中等

4.最大連續1的個數Ⅲ:1004. 最大連續1的個數 III - 力扣(LeetCode)中等

5.找到字符串中所有字母異位詞:438. 找到字符串中所有字母異位詞 - 力扣(LeetCode)中等

6.水果成籃:904. 水果成籃 - 力扣(LeetCode)中等

7.串聯所有單詞的子串:30. 串聯所有單詞的子串 - 力扣(LeetCode)困難

8.最小覆蓋子串:76. 最小覆蓋子串 - 力扣(LeetCode)困難

滑動窗口。1.特點:具有單調性。2.步驟:進窗口、判斷窗口、出窗口。然后記錄結果在三個步驟其一

1.長度最小的子數組

(1)鏈接:209. 長度最小的子數組 - 力扣(LeetCode)中等

題意:找到一個最短的子數組(連續),要求子數組的和>=目標值。

(2)思路:滑動窗口不斷求和,當和>=目標值時,則判斷結果并出窗口

可以使用滑動窗口的原因是:數組元素都是正整數,不斷向右遞增時數組和是遞增的

(3)代碼

class Solution {public int minSubArrayLen(int target, int[] nums) {int ret = Integer.MAX_VALUE, sum = 0;for(int left=0,right=0;right<nums.length;right++) {sum += nums[right]; //1.進窗口while(sum >= target) { //2.判斷ret = Math.min(right-left+1,ret); //3.記錄結果sum -= nums[left++]; //4.出窗口}}return ret==Integer.MAX_VALUE?0:ret;}
}
2.無重復字符的最長子串

(1)鏈接:3. 無重復字符的最長子串 - 力扣(LeetCode)中等

題意:找出沒有重復字符的最長子數組,也就是求最長子數組的長度

(2)思路:也是找子數組,所以可以使用滑動窗口。

如何判斷是否有重復元素,則可以遍歷窗口內元素即可

(3)代碼

class Solution {public int lengthOfLongestSubstring(String s) {//如何判斷窗口內是否有重復元素??從窗口左邊開始遍歷,是否和新進入的窗口值相同//做法:始終保持窗口內的元素是不重復的int ret = 0;int n = s.length();for(int left=0,right=0;right<n;right++) {//1.入窗口--這里默認窗口為[left,right]的元素int cur = left;while(cur < right) { //2.判斷-窗口內是否有重復元素if(s.charAt(cur) == s.charAt(right)) {left = cur+1; //3.出窗口}cur++;}ret = Math.max(ret,right-left+1); //4.記錄結果-此時的窗口內保證無重復元素}return ret;}
}
3.將x減少到0的最小操作數

(1)鏈接:1658. 將 x 減到 0 的最小操作數 - 力扣(LeetCode)中等

題意:每次從最左或者最右選取一個數(選取完默認從數組中刪除),要求和為x且長度最小的。這是正向的意思,我們反過來理解:在中間選取一段連續區間和為sum-x,要求長度最長

(2)思路:連續數組且都是正整數,且和為sum-x

(3)代碼

class Solution {public int minOperations(int[] nums, int x) {//題意:每次選擇最左邊或者最右邊的數,是否可以組合成x。//題意轉換:數組和為sum,是否存在這樣一個區間,使得和為sum-x的,要長度最大int sum = 0, n = nums.length;for(int i=0;i<n;i++) {sum += nums[i];}int target = sum - x, len = -1, path = 0;for(int left=0,right=0;right<n;right++) {path += nums[right]; //1.入窗口while(left < n && path > target) { //2. 判斷//3.出窗口path -= nums[left];left++;}//4.記錄結果if(path == target) len = Math.max(len,right-left+1);}return len==-1?-1:n-len;}
}
4.最大連續1的個數Ⅲ

(1)鏈接:1004. 最大連續1的個數 III - 力扣(LeetCode)中等

題意:找出含有最多1的子數組,有k次機會可以將0變成1

(2)思路:連續子數組,可以使用滑動窗口。窗口內維護1的個數和將0變成1的次數

出窗口的條件:當0的個數大于K次時出窗口

(3)代碼

class Solution {public int longestOnes(int[] nums, int k) {//窗口內維護1,和可將0變成1的個數int n = nums.length;int ret = 0, count=0;for(int left=0,right=0;right<n;right++) {if(nums[right] == 0) count++; //1.入窗口while(count > k) { //2.判斷//3.出窗口if(nums[left] == 0) count--;left++;}//4.記錄結果ret = Math.max(ret,right-left+1);}return ret;}
}
5.找到字符串中所有字母異位詞

(1)鏈接:438. 找到字符串中所有字母異位詞 - 力扣(LeetCode)中等

題意:給兩個字符串,要求在s字符串中找出所有和p字符串互為異位詞的字符串

(2)思路:(窗口不斷向右移動,字母的數量是不斷增加的)窗口只需要維護p長度的大小即可,每次到達該長度,就判斷一下是否互為異位詞,判斷完記錄結果并出窗口。

用兩個計數數組判斷是否互為異位詞

(3)代碼

class Solution {public List<Integer> findAnagrams(String s, String p) {//如何判斷異位詞??int[] pMap = new int[26];for(int i=0;i<p.length();i++) {pMap[p.charAt(i)-97]++;}int[] sMap = new int[26];List<Integer> ret = new ArrayList<>();for(int left=0,right=0;right<s.length();right++) {//1.入窗口sMap[s.charAt(right)-97]++;//2.判斷if(right-left+1 == p.length()) {//3.判斷是否為異位詞boolean update = true;for(int i=0;i<26;i++) {if(sMap[i] != pMap[i]) {update = false;break;}}//4.記錄結果if(update) ret.add(left);//5.出窗口sMap[s.charAt(left++)-97]--;}}return ret;}
}
6.水果成籃

(1)鏈接:904. 水果成籃 - 力扣(LeetCode)中等

題意:給一個數組,不同的值代表不同的水果。最多只能采摘兩種水果,求可以采摘的最多數量是多少?

(2)思路:不斷向右移動,數量增加,且是連續子數組。

每次入窗口判斷對應的map是否為空,為空則為不同的種類。當種類數大于2說明超出需要出窗口;最后記錄結果即可。

(3)代碼

class Solution {public int totalFruit(int[] fruits) {//如何判斷水果的種類和之前的相同或者不同??可以用map記錄,如果=0則不同int[] map = new int[fruits.length];int ret = 0, kind = 0;for(int left = 0,right = 0; right < fruits.length; right++) {//1.入窗口并判斷水果種類是否增加if(map[fruits[right]] == 0) {kind++;}map[fruits[right]]++;//2.判斷-種類是否超出2種while(kind > 2) {//3.出窗口map[fruits[left++]]--;if(map[fruits[left-1]] == 0) kind--;}//4.記錄結果ret = Math.max(ret,right-left+1);}return ret;}
}
7.串聯所有單詞的子串

(1)鏈接:30. 串聯所有單詞的子串 - 力扣(LeetCode)困難

題意:有一個字符串數組words,里面的字符串長度都相同,把它們以任何的順序組成一個字符串(單個單詞內部順序不變)。然后求該字符串在字符串s中出現的起始位置

(2)思路:把整個單詞看成一個字母,也就是找這些字母的異位詞出現的起始位置

1)先用Map存儲words中字符串出現的頻率

2)滑動窗口每次移動len步,每次進入窗口的單詞為right+len

3)進入窗口后,同時記錄map中,并判斷該單詞是否為有效單詞,如果有效則記錄count

4)如果count達到有效次數,則記錄結果

5)滑動窗口需要執行len次

(3)代碼:

class Solution {public List<Integer> findSubstring(String s, String[] words) {int n = words.length, len = words[0].length();Map<String,Integer> mapW = new HashMap<>(); //記錄words里面單詞出現的頻率for(String x : words) {mapW.put(x,mapW.getOrDefault(x,0)+1);}List<Integer> ret = new ArrayList<>();for(int k=0;k<len;k++) { //控制滑動窗口執行的次數Map<String,Integer> mapS = new HashMap<>(); //記錄窗口內里面單詞出現的頻率for(int left=k,right=k,count=0;right+len <= s.length();right+=len) {//每次進窗口為right+len, 用count記錄窗口內有效字符串的個數//1.進窗口String in = s.substring(right,right+len); //[right,right+len-1]mapS.put(in,mapS.getOrDefault(in,0)+1);//2.維護窗口內有效字符串個數if(mapS.get(in) <= mapW.getOrDefault(in,0)) count++; //如果in字符串在mapW也存在,且個數<=,說明是有效字符串//3.判斷if(right-left+1 > len * n) {String out = s.substring(left,left+len);if(mapS.get(out) <= mapW.getOrDefault(out,0)) count--; //如果out字符串在mapW也存在,且個數<=,說明是有效字符串//4.出窗口mapS.put(out,mapS.get(out)-1);left += len;}//5.記錄結果if(count == n) ret.add(left);}}return ret;}
}

(*)不使用該計數數組,使用map如果做?

1)借助一個變量count統一窗口中有效“字符”的個數。這里的字符可能是單個字母,也可能是一個字符串。

2)進窗口時,判斷兩個hash中的字符個數,如果進窗口的hash個數小于原hash個數

8.最小覆蓋子串

(1)鏈接:76. 最小覆蓋子串 - 力扣(LeetCode)困難

題意:在字符串s中找出一個連續的子串,要求這個子串包含字符串t。并且要返回這個最短的子串

(2)思路:使用兩個哈希表或者計數數組,維護有效數字的窗口即可。

只需要記錄最短的長度和起始位置。

(3)代碼

使用Map接口:

class Solution {public String minWindow(String s, String t) {Map<Character,Integer> mapT = new HashMap<>();for(int i=0;i<t.length();i++) {char ch = t.charAt(i);mapT.put(ch,mapT.getOrDefault(ch,0)+1);}int minLen = Integer.MAX_VALUE, begin = -1;Map<Character,Integer> mapS = new HashMap<>();for(int left = 0,right = 0,count = 0;right < s.length();right++) {//1.入窗口char ch = s.charAt(right);mapS.put(ch,mapS.getOrDefault(ch,0)+1);//2.判斷是否有效if(mapS.get(ch) <= mapT.getOrDefault(ch,0)) count++;//3.維護窗口while(left <= right && count >= t.length()) {//4.記錄結果if(count == t.length() && minLen > right - left + 1) {begin = left;minLen = right - left + 1;}//5.出窗口char out = s.charAt(left);if(mapS.get(out) <= mapT.getOrDefault(out,0)) count--;mapS.put(out,mapS.get(out)-1);left++;}           }if(begin == -1) return new String();else return s.substring(begin,begin+minLen);}
}

使用數組模擬:

class Solution {public String minWindow(String ss, String tt) {char[] s = ss.toCharArray();char[] t = tt.toCharArray();int[] mapT = new int[128];//記錄第一輪mapint kinds = 0;for(int i = 0;i < t.length;i++) {if(mapT[t[i]] == 0) kinds++;mapT[t[i]]++;}int[] mapS = new int[128];int minlen = Integer.MAX_VALUE, begin = -1;for(int left=0,right=0,count=0;right<s.length;right++) {//1.入窗口char in = s[right];mapS[in]++;//2.判斷是否為有效種類if(mapS[in] == mapT[in]) count++;//3.循環while(count == kinds) {//4.記錄窗口if(right-left+1 < minlen) {begin = left;minlen = right-left+1;}//5.出窗口char out = s[left++];if(mapS[out] == mapT[out]) count--;mapS[out]--;}}if(begin == -1) return new String();else return ss.substring(begin,begin+minlen);}   
}

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

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

相關文章

Witsbb健敏思是哪個國家的品牌?澳洲純凈溯源,100+過敏原排除的敏寶專研品牌

在為敏感體質寶寶挑選營養補充品時&#xff0c;“品牌來源是否可靠”“品控標準是否嚴格”往往是寶爸寶媽的首要考量。源自澳大利亞的Witsbb健敏思&#xff0c;作為澳企Forestpark旗下的綜合膳食營養補充品牌&#xff0c;從誕生起便根植于澳洲嚴苛的保健品監管體系&#xff0c;…

gdbserver遠程調試和交叉編譯gdb

1、交叉編譯gdb 1.1下載源碼 Gdb源碼&#xff1a;wget https://ftp.gnu.org/gnu/gdb/gdb-15.2.tar.xz Gdb依賴的源碼&#xff1a;GMP、MPFR、ncurses&#xff08;圖形庫&#xff09; GMP源碼&#xff1a;wget https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz MPFR源碼&#xff1…

UE5.5模型導入FBX強制x軸向前Force Front XAxis

很多軟件軸向都是不同的 , 所以模型導入虛幻的時候 可以勾選Force Front XAxisUE5.5 在右上角設置 點擊右上角三個點就可以看到強制前X軸

Docker中如何記錄非交互式連接ssh用戶操作的所有命令記錄?

網羅開發&#xff08;小紅書、快手、視頻號同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企業從事人工智能項目研發管理工作&#xff0c;平時熱衷于分享各種編程領域的軟硬技能知識以及前沿技術&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…

渦旋場和撓場的對偶性方程組

要將渦旋場與撓場的動態對偶性以麥克斯韋方程組的形式嵌入愛因斯坦-嘉當理論的彎曲時空框架中。一、符號與幾何基礎1. 基本張量定義 度規張量&#xff1a; g_{\mu\nu} &#xff08;描述時空彎曲&#xff0c; \mu,\nu 0,1,2,3 &#xff09;。仿射聯絡&#xff1a; \Gamma^\la…

8.28日QT

思維導圖#include <iostream>using namespace std;int main() {int a0,b0,c0,d0;string i;cout << "請輸入一個字符串" << endl;getline(cin,i);int yi.size()-1;while(1){if(a<i[y]&&i[y]<z){aa1;}else if(A<i[y]&&i[y]…

跨網絡通信:路由器如何實現全球互聯

目錄 一、跨網絡的兩臺主機通信 二、采用不同通信標準的兩個局域網內的主機通信 三、路由器實現的“認路”功能、數據傳輸&#xff1a;封裝與解封裝 四、認識IP地址 五、為什么訪問目標主機需要經過路由器&#xff1f; 1、網絡劃分 2、尋址與轉發 六、目的IP地址的核心意…

HTTP 頭

HTTP 頭&#xff08;HTTP Header&#xff09;是 HTTP 請求/響應中用于傳遞元數據的關鍵部分&#xff0c;分為 請求頭&#xff08;Request Header&#xff09;、響應頭&#xff08;Response Header&#xff09;、通用頭&#xff08;General Header&#xff09; 和 實體頭&#x…

vue 海康視頻插件

背景&#xff1a; 在vue項目中&#xff0c;需要在pc端播放視頻&#xff0c;播放的視頻包括視頻實時、視頻回放等。 寫文思路&#xff1a; 海康視頻對接流程&#xff0c;了解海康視頻插件&#xff0c;前端開發項目并引入依賴&#xff0c;前端開發封裝的組件&#xff0c;組件的調…

【URP】Unity 插入自定義RenderPass

【從UnityURP開始探索游戲渲染】專欄-直達 自定義渲染通道是一種改變通用渲染管道&#xff08;URP&#xff09;如何渲染場景或場景中的對象的方法。自定義呈現通道(RenderPass)包含自己的Render代碼&#xff0c;可以在注入點將其添加到RenderPass中。 添加自定義呈現通道(Rend…

DevSecOps 集成 CI/CD Pipeline:實用指南

就在你以為軟件開發已無簡化的余地時&#xff0c;新的解決方案應運而生 隨著軟件開發幾乎每天都在攀升&#xff0c;組織不斷嘗試以前所未有的速度交付新功能和應用程序。雖然持續集成和持續交付 &#xff08;CI/CD&#xff09; Pipeline 徹底改變了軟件部署&#xff0c;但它們…

vue2+elementui 表格單元格增加背景色,根據每列數據的大小 顏色依次變淺顯示

注釋&#xff1a; vue2elementui 表格列實現一個功能&#xff0c;給定兩個顏色&#xff1a;紅色 #f96d6f 和 綠色 #63be7b&#xff0c;列數據正數時表格單元格背景色為紅色&#xff0c;列數據負數時表格單元格背景色為綠色&#xff0c;根據數據的大小顏色依次越來越淡&#xff…

【JavaEE】(19) MyBatis-plus

一、MyBatis Generator 為 MyBastis 框架設計的代碼生成工具&#xff0c;簡化持久層編碼工作。根據數據庫表自動生成 Java 實體類、Mapper 接口、SQL 的 xml 文件。讓開發者專注于業務邏輯。 1、引入插件 MyBatis 官網搜索 MyBatis Generator 插件&#xff1a;Running MyBatis…

Android之騰訊TBS文件預覽

文章目錄前言一、效果圖二、實現步驟1.去官網注冊并創建應用[騰訊官網](https://console.cloud.tencent.com/tbs/client)2.下載arr文件并引入[騰訊TBS](https://download.csdn.net/download/Android_Cll/91764395)3.application實例化4.activity實例化5.下載網絡文件6.PreviewA…

基于微信小程序的化妝品成分查詢系統源碼

源碼題目&#xff1a;基于微信小程序的化妝品成分查詢系統源碼?? 文末聯系獲取&#xff08;含源碼、技術文檔&#xff09;博主簡介&#xff1a;10年高級軟件工程師、JAVA技術指導員、Python講師、文章撰寫修改專家、Springboot高級&#xff0c;歡迎高校老師、同行交流合作。畢…

STM32 啟動執行邏輯與代碼燒入方法詳解:從底層原理到實操落地

STM32 啟動執行邏輯與代碼燒入方法詳解&#xff1a;從底層原理到實操落地背景概要STM32啟動和執行的核心邏輯鏈條代碼燒入到STM32的途徑方法結束語背景概要 在學習STM32時候我們知道代碼需要通過一些下載器&#xff08;如ST-Link、J-Link&#xff09;或者串口下載燒入到STM32芯…

Go對接印度股票數據源指南:使用StockTV API

一、StockTV API簡介 StockTV提供全球200國家的實時金融數據&#xff0c;覆蓋股票、外匯、期貨和加密貨幣市場。針對印度市場&#xff08;國家ID14&#xff09;&#xff0c;其主要優勢包括&#xff1a; 毫秒級低延遲響應7x24小時穩定服務日均處理億級數據免費技術支持 官方資源…

ESP8266:Arduino學習

ESP8266一&#xff1a;環境搭建使用Ardino框架&#xff0c;在官網下載&#xff0c;下載離線的支持包二&#xff1a;實現簡單的項目1. 點燈{pinMode(LED_PIN, OUTPUT); // 設置引腳為輸出模式digitalWrite(LED_PIN, HIGH); // 點亮 LED}I/O引腳的三種模式分別為&#xff1a;INPU…

青少年軟件編程(python六級)等級考試試卷-客觀題(2023年3月)

更多內容和歷年真題請查看網站&#xff1a;【試卷中心 -----> 電子學會 ----> 機器人技術 ----> 六級】 網站鏈接 青少年軟件編程歷年真題模擬題實時更新 青少年軟件編程&#xff08;python六級&#xff09;等級考試試卷-客觀題&#xff08;2023年3月&#xff09…

mongodb influxdb

、您需要提前配置 MongoDB 和 InfluxDB。讓我幫您說明配置步驟&#xff1a; MongoDB 配置 啟動 MongoDB 容器后&#xff0c;進入容器創建數據庫&#xff1a; # 進入 MongoDB 容器 docker exec -it mongo mongosh -u root -p 123456# 創建 product 數據庫 use product# 創建集合…