LeetCode-刷題記錄-滑動窗口合集(本篇blog會持續更新哦~)

一、滑動窗口概述

滑動窗口(Sliding Window)是一種用于解決數組(或字符串)中子數組(或子串)問題的有效算法。

在這里插入圖片描述

Sliding Window核心思想:

滑動窗口技術的基本思想是維護一個窗口(一般是一個子數組或子串),該窗口在數組上滑動,并在滑動過程中更新窗口的內容。

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

通過滑動窗口,可以在 ( O(n) ) 的時間復雜度內解決很多子數組(子串)問題,其中 ( n ) 是數組(字符串)的長度。

基本步驟:

  1. 初始化窗口: 定義一個窗口的起始位置和結束位置,通常是兩個指針 leftright
  2. 滑動窗口: 不斷地增加 right 指針來擴大窗口,直到窗口滿足某個條件為止。

在這里插入圖片描述

  1. 更新窗口: 一旦滿足條件,嘗試縮小窗口大小,即增加 left 指針,直到條件不滿足為止。
  2. 記錄結果: 在滑動窗口的過程中,根據題目要求來記錄最終的結果。

二、習題合集

LeetCode 209 長度最小的子數組

在這里插入圖片描述

  • 滑動窗口O(N)解法:
class Solution {public int minSubArrayLen(int target, int[] nums) {int n = nums.length;  // 數組的長度int ans = Integer.MAX_VALUE;  // 初始化結果為最大值,用于存儲最短子數組的長度int l = 0;  // 左指針,指向滑動窗口的起始位置int sum = 0;  // 記錄滑動窗口內元素的和for (int r = 0; r < n; r++) {  // 右指針,擴展滑動窗口sum += nums[r];  // 將右指針指向的元素加入窗口while (sum >= target) {  // 當窗口內元素和大于等于目標值時,嘗試縮小窗口ans = Math.min(ans, r - l + 1);  // 更新最短子數組的長度sum -= nums[l];  // 縮小窗口,左指針向右移動,減少窗口內的元素和l++;  // 左指針右移}}return ans == Integer.MAX_VALUE ? 0 : ans;  // 如果找不到滿足條件的子數組,返回0;否則返回最短子數組的長度}
}

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

在這里插入圖片描述


  • 第一版滑動窗口
class Solution {public int lengthOfLongestSubstring(String s) {Map<Character, Integer> map = new HashMap<>(); // 創建一個哈希表,用來記錄字符及其出現的最后位置int n = s.length(); // 字符串的長度int l = 0, ans = 0; // l表示當前不重復子串的起始位置,ans用來記錄最長不重復子串的長度for (int r = 0; r < n; r++) {char c = s.charAt(r); // 獲取當前字符if (map.containsKey(c)) {//如果曾經出現的 字母 還在窗口內 —— l更新到 該位置+1//如果曾經出現的 字母 已不在當前窗口內了—— 則不需要更新l = Math.max(l,map.get(c)+1);}map.put(c, r); // 更新當前字符的最后出現位置為當前索引rans = Math.max(ans, r - l + 1); // 更新最長不重復子串的長度}return ans; // 返回最長不重復子串的長度}
}

要理解 left = Math.max(left,map.get(s.charAt(i)) + 1);需要回歸到滑動窗口的原理上。

窗口中始終是無重復字母的字符串。 我們通過窗口的左界和右界控制窗口。

右界不用特意操作,因為它是+1,+1地漲上去,記得在循環里+1就好。

左界:每當有一個字符曾經出現過,就需要判斷左界。

重點來了:

若,被判斷的字符上一次出現的位置就在滑動窗口內,即 [ i,j ] 內, 則需要left改變位置,改變為該字符上次出現位置+1。也就是left = map.get(s.charAt(i)) + 1的情況。

例如:

abcdb中,窗口正常運行到abcd時,下一個字符為b,b上一次出現在實在窗口里,所以需要把left設置為上一次出現的位置+1的位置,得到新的窗口為cdb,不然你不這樣設置,窗口里有重復的字符(bcdb),不符合窗口的定義。

若,不在滑動窗口內,則不用管。 不用管是因為:窗口中字符串沒有重復字符。窗口符合定義。所以left = left。 left = left就表示這個窗口暫時不變。

在這里插入圖片描述


  • 第二版優化的滑動窗口:
class Solution {public int lengthOfLongestSubstring(String s) {// 記錄字符上一次出現的位置int[] last = new int[128]; // 創建一個長度為128的整型數組,用來記錄ASCII碼表中每個字符上一次出現的位置for(int i = 0; i < 128; i++) {last[i] = -1; // 初始化數組,所有字符的上一次出現位置都設為-1,表示尚未出現過}int n = s.length(); // 字符串s的長度int res = 0; // 用于記錄最長的不重復子串的長度int start = 0; // 窗口開始位置,用來維護當前不重復子串的起始位置for(int i = 0; i < n; i++) {int index = s.charAt(i); // 獲取當前字符的ASCII碼作為索引start = Math.max(start, last[index] + 1); // 更新窗口的起始位置,確保不重復的起點res = Math.max(res, i - start + 1); // 更新最大的不重復子串長度last[index] = i; // 更新當前字符的最后出現位置為當前索引i}return res; // 返回最長的不重復子串的長度}
}

LeetCode 187 重復的DNA序列

在這里插入圖片描述

  • 哈希表法~
class Solution {public List<String> findRepeatedDnaSequences(String s) {List<String> ans = new ArrayList<>(); // 用于存放重復的DNA序列int n = s.length(); if (n < 10) return ans; // 如果字符串長度小于10,直接返回空列表,因為無法形成長度為10的序列Map<String, Integer> map = new HashMap<>(); // 創建一個哈希表,用來記錄每個長度為10的子序列及其出現的次數map.put(s.substring(0, 10), 1); // 初始化,將第一個長度為10的子序列放入哈希表中for (int i = 1; i + 10 <= n; i++) { // 從第二個子序列開始遍歷到倒數第十個子序列String ss = s.substring(i, i + 10); // 獲取當前長度為10的子序列if (map.getOrDefault(ss, 0) == 1) { // 如果該子序列已經在哈希表中出現過一次ans.add(ss); // 將該子序列加入結果列表}map.put(ss, map.getOrDefault(ss, 0) + 1); // 更新哈希表中該子序列的出現次數}return ans; // 返回重復的DNA序列列表}
}
  • 滑動窗口法~
class Solution {// 滑動窗口法查找重復的長度為10的DNA序列public List<String> findRepeatedDnaSequences(String s) {List<String> ans = new ArrayList<>(); // 用于存放重復的DNA序列int n = s.length(); // 字符串的長度if (n < 10) return ans; // 如果字符串長度小于10,直接返回空列表,因為無法形成長度為10的序列StringBuilder sb = new StringBuilder(s.substring(0, 10)); // 初始化第一個長度為10的子串Set<String> set = new HashSet<>(); // 使用集合來記錄出現過的子串set.add(sb.toString()); // 將第一個子串添加到集合中for (int i = 1; i + 10 <= n; i++) {String str = s.substring(i, i + 10); // 獲取當前長度為10的子串if (set.contains(str)) { // 如果集合中已經包含當前子串if (!ans.contains(str)) // 且列表中還未包含該子串ans.add(str); // 將該子串添加到列表中} else { // 如果集合中不包含當前子串set.add(str); // 將當前子串添加到集合中}}return ans; // 返回存放了重復DNA序列的列表}
}

LeetCode 424 替換后的最長重復字符

在這里插入圖片描述
在這里插入圖片描述

  • 核心思想:

相同的最長子字符串(窗口) = 窗口內最大字符個數 + 反轉次數

一旦 窗口長度 - 窗口內最大字符個數 > 反轉次數 窗口開始移動

public int characterReplacement(String s, int k) {int n = s.length();if(n<2) return n;int ans = 0; // 用于存儲最長連續相同字符的子串的長度int maxFreq = 0; // 用于存儲當前窗口內出現次數最多的字符的次數char[] c = s.toCharArray();int[] freq = new int[26]; // 記錄當前窗口內每個字符出現的次數int left = 0; // 滑動窗口的左邊界for (int right = 0; right < n; right++) {++freq[c[right] - 'A']; // 更新右邊界字符的出現次數maxFreq = Math.max(maxFreq, freq[c[right] - 'A']); // 更新最大出現次數// 如果當前窗口的大小減去出現次數最多的字符的次數大于k,則需要縮小窗口// 使得窗口內可以通過替換字符使其變成連續相同字符的子串if (right - left + 1 > maxFreq + k) {freq[c[left] - 'A']--; // 縮小窗口時,更新左邊界字符的出現次數left++; // 縮小窗口}// 更新最長連續相同字符的子串的長度ans = Math.max(ans, right - left + 1);}return ans;}


更新于:

在這里插入圖片描述

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

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

相關文章

怎樣在Python中使用oobabooga的API密鑰,通過端口5000獲取模型列表的授權

題意&#xff1a; oobabooga-textgen-web-ui how to get authorization to view model list from port 5000 via the oobas api-key in python 怎樣在Python中使用oobabooga的API密鑰&#xff0c;通過端口5000獲取模型列表的授權 問題背景&#xff1a; I wish to extract an…

fastapi+vue3前后端分離開發第一個案例整理

開發思路 1、使用fastapi開發第一個后端接口 2、使用fastapi解決cors跨域的問題。cors跨域是瀏覽器的問題&#xff0c;只要使用瀏覽器&#xff0c;不同IP或者不同端口之間通信&#xff0c;就會存在這個問題。前后端分離是兩個服務&#xff0c;端口不一樣&#xff0c;所以必須要…

PCA和PCoA分析的python代碼

主成分分析(PCA)和主坐標分析(PCoA)都是數據降維和可視化的常用方法,但它們在適用場景和計算方法上有一些重要區別。 主成分分析(PCA) 定義: PCA是一種線性降維方法,通過正交變換將原始數據轉化為一組線性不相關的變量(主成分)。這些主成分是數據中方差最大的方向。…

XLSX + LuckySheet + LuckyExcel實現前端的excel預覽

文章目錄 功能簡介簡單代碼實現效果參考 功能簡介 通過LuckyExcel的transformExcelToLucky方法&#xff0c; 我們可以把一個文件直接轉成LuckySheet需要的json字符串&#xff0c; 之后我們就可以用LuckySheet預覽excelLuckyExcel只能解析xlsx格式的excel文件&#xff0c;因此對…

.NET 漏洞分析 | 某ERP系統存在SQL注入

01閱讀須知 此文所提供的信息只為網絡安全人員對自己所負責的網站、服務器等&#xff08;包括但不限于&#xff09;進行檢測或維護參考&#xff0c;未經授權請勿利用文章中的技術資料對任何計算機系統進行入侵操作。利用此文所提供的信息而造成的直接或間接后果和損失&#xf…

Java中s-EJB 與 e-EJB的區別

在Java中&#xff0c;關于“s-EJB”與“e-EJB”的區分&#xff0c;實際上可能存在一定的誤解或混淆&#xff0c;因為在標準的EJB&#xff08;Enterprise JavaBeans&#xff09;術語中&#xff0c;并沒有直接稱為“s-EJB”和“e-EJB”的明確分類。然而&#xff0c;為了嘗試解答這…

【Postman gRPC測試全攻略】探索微服務通信的新紀元

標題&#xff1a;【Postman gRPC測試全攻略】探索微服務通信的新紀元 gRPC是一種高性能、開源和通用的RPC框架&#xff0c;由Google主導開發&#xff0c;它使用Protocol Buffers作為接口描述語言和消息交換格式。Postman作為API開發的利器&#xff0c;也提供了對gRPC服務的測試…

封裝2個函數

1 #include "key1.h"2 //封裝EXTI章節函數3 void hal_exti_init(int exti,unsigned int i)4 {5 switch(exti)6 {7 case 9:8 //使能GPIOF外設時鐘9 RCC->MP_AHB4ENSETR | (0x1<<5);10 //將PF9設置為輸出模式11 …

MyBatis(22)如何在 MyBatis 中使用注解而不是 XML 映射文件

在 MyBatis 中&#xff0c;使用注解而不是 XML 映射文件來進行 SQL 映射是一種更為簡潔直觀的方式&#xff0c;尤其適用于 SQL 語句較少的場景。通過注解&#xff0c;開發者可以直接在接口方法上聲明 SQL 語句&#xff0c;這樣可以減少項目中的配置文件數量&#xff0c;使得項目…

學習筆記——動態路由——OSPF(認證)

十二、OSPF鄰居認證 1、OSPF鄰居認證概述 鏈路是路由器接口的另一種說法&#xff0c;因此OSPF也稱為接口狀態路由協議。OSPF通過路由器之間通告網絡接口的狀態來建立鏈路狀態數據庫&#xff0c;生成最短路徑樹&#xff0c;每個OSPF路由器使用這些最短路徑構造路由表。 OSPF認…

基于Vue框架實現的記事本

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>懶人記事本</title><style>body {fo…

深度網絡現代實踐 - 深度前饋網絡之反向傳播和其他的微分算法篇

序言 反向傳播&#xff08;Backpropagation&#xff0c;簡稱backprop&#xff09;是神經網絡訓練過程中最關鍵的技術之一&#xff0c;尤其在多層神經網絡中廣泛應用。它是一種與優化方法&#xff08;如梯度下降法&#xff09;結合使用的算法&#xff0c;用于計算網絡中各參數的…

大數據面試題之數倉(1)

目錄 介紹下數據倉庫 數倉的基本原理 數倉架構 數據倉庫分層(層級劃分)&#xff0c;每層做什么?分層的好處? 數據分層是根據什么? 數倉分層的原則與思路 知道數倉建模常用模型嗎?區別、優缺點? 星型模型和雪花模型的區別?應用場景?優劣對比 數倉建模有哪些方式…

【Symfony社區全接觸】深入探索文檔與支持資源

標題&#xff1a;【Symfony社區全接觸】深入探索文檔與支持資源 Symfony是一個強大的PHP框架&#xff0c;擁有一個活躍的開發者社區和豐富的文檔資源。這些資源對于學習和使用Symfony至關重要。本文將詳細介紹Symfony的文檔和社區支持&#xff0c;包括官方文檔、社區論壇、郵件…

如何計算弧線彈道的落地位置

1&#xff09;如何計算弧線彈道的落地位置 2&#xff09;Unity 2021 IL2CPP下使用Protobuf-net序列化報異常 3&#xff09;編譯問題&#xff0c;用Mono可以&#xff0c;但用IL2CPP就報錯 4&#xff09;Wwise的Bank在安卓上LoadBank之后&#xff0c;播放沒有聲音 這是第393篇UWA…

02 數據加工層 如何搭建用戶與內容的標準規范體系

你好&#xff0c;我是周大壯。 01 講我們提到了個性化流量分發體系的四個階段&#xff0c;并著重講解了數據采集階段的內容。那么&#xff0c;這一講我們主要圍繞數據加工階段的內容進行詳細講解。 在課程開始之前&#xff0c;我們先舉一個場景進行說明。 近年來&#xff0c…

靜態方法與實例方法的區別

靜態方法與實例方法的區別 1、靜態方法&#xff08;Static Methods&#xff09;1.1 調用方式1.2 訪問權限 2、實例方法&#xff08;Instance Methods&#xff09;2.1 調用方式2.2 訪問權限 3、總結 &#x1f496;The Begin&#x1f496;點點關注&#xff0c;收藏不迷路&#x1…

大數據面試題之數倉(2)

目錄 維度表和事實表的區別? 什么是ER模型? OLAP、OLTP解釋(區別)三范式是什么&#xff0c;舉些例子 維度設計過程&#xff0c;事實設計過程 維度設計中有整合和拆分&#xff0c;有哪些方法&#xff0c;并詳細說明 事實表設計分幾種&#xff0c;每一種都是如何在業…

【C++】解決 C++ 語言報錯:Invalid Array Index

文章目錄 引言 無效數組索引&#xff08;Invalid Array Index&#xff09;是 C 編程中常見且危險的錯誤之一。當程序試圖使用不合法的索引訪問數組時&#xff0c;就會發生無效數組索引錯誤。這種錯誤不僅會導致程序崩潰&#xff0c;還可能引發不可預測的行為和安全漏洞。本文將…

【PB案例學習筆記】-28制作一個右鍵菜單

寫在前面 這是PB案例學習筆記系列文章的第28篇&#xff0c;該系列文章適合具有一定PB基礎的讀者。 通過一個個由淺入深的編程實戰案例學習&#xff0c;提高編程技巧&#xff0c;以保證小伙伴們能應付公司的各種開發需求。 文章中設計到的源碼&#xff0c;小凡都上傳到了gite…