【LeetCode hot100|Week2】滑動窗口,子串

筆記用于個人復習和鞏固,題解非原創,參考LeetCode官方題解以及各個大佬的解法,希望給大家帶來幫助,同時筆記也能督促我學習進步

這周主要把滑動窗口和子串的題目刷了一遍

文章目錄

  • Week2
    • D1 滑動窗口
      • 209. 長度最小的子數組
      • 713. 乘積小于 K 的子數組
      • 3. 無重復字符的最長子串
    • D2 定長滑窗&不定長滑窗
      • 定長滑窗
        • 定長滑窗套路
      • 不定長滑窗
    • D3
      • 560. 和為 K 的子數組
        • 暴力
        • 前綴和+哈希表
    • D4
      • 239. 滑動窗口最大值
        • 單調隊列
    • D5
      • 76. 最小覆蓋子串
    • D6
      • 53. 最大子數組和
        • 貪心
        • 動態規劃
    • D7
      • 56. 合并區間

Week2

D1 滑動窗口

只有當數組中所有數都是非負數時,才能使用滑動窗口。

如果數組中包含負數不能使用標準的滑動窗口

滑動窗口的核心前提:

當窗口擴大時,和變大;窗口縮小時,和變小。

209. 長度最小的子數組

209. 長度最小的子數組

class Solution {public int minSubArrayLen(int target, int[] nums) {int n = nums.length;int ans = n + 1;int sum = 0;int left = 0;for(int right = 0;right < n;right++){sum += nums[right];while(sum >= target){ans = Math.min(ans,right - left + 1);sum -= nums[left];left++;}}return ans <= n ? ans : 0;}
}

713. 乘積小于 K 的子數組

713. 乘積小于 K 的子數組

class Solution {public int numSubarrayProductLessThanK(int[] nums, int k) {if(k <= 1){return 0;}int n = nums.length;int ans = 0;int prod = 1;int left = 0;for(int right = 0;right < n;right++){prod *= nums[right];while(prod >= k){ //不滿足要求prod /= nums[left];left++; //縮小窗口}ans += right - left + 1;}return ans;}
}

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

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

class Solution {public int lengthOfLongestSubstring(String S) {char[] s = S.toCharArray();int ans = 0;int n = s.length;int left = 0;int[] cnt = new int[128];for(int right = 0;right < n;right++){char c = s[right];cnt[c]++;while(cnt[c] > 1){ //窗口有重復字符cnt[s[left]]--;//移除窗口左端點字符left++;//縮小窗口}ans = Math.max(ans,right - left + 1);}return ans;}
}

D2 定長滑窗&不定長滑窗

定長滑窗

class Solution {public List<Integer> findAnagrams(String s, String p) {List<Integer> ans = new ArrayList<>();int n = s.length(); //測量String的長度用.length()int[] cntP = new int[26]; //統計p的每種字母的出現次數int[] cntS = new int[26]; //統計s的長為p.length()的子串s'的每種字母的出現次數for(char c:p.toCharArray()){cntP[c - 'a']++;}for(int right = 0;right < n;right++){cntS[s.charAt(right) - 'a']++;int left = right - p.length() + 1;if(left < 0){continue; //窗口長度不夠}if(Arrays.equals(cntS,cntP)){ans.add(left);}cntS[s.charAt(left) - 'a']--; //左端字母離開窗口}return ans;}
}

Arrays.equals(cntS, cntP) 是 Java 中用來 判斷兩個數組是否“完全相同” 的標準方法

? 它比較的是:

兩個數組在以下方面是否完全一致:

比較項是否比較
1. 數組長度
2. 每個對應位置的元素值
3. 元素順序是(順序不同 → 不相等)

如果以上全部相同,返回 true;否則返回 false


定長滑窗套路

窗口右端點在 i 時,由于窗口長度為 k,所以窗口左端點為 i?k+1。

三步:入-更新-出

  1. 入:下標為 i 的元素進入窗口,更新相關統計量。如果窗口左端點 i?k+1<0,則尚未形成第一個窗口,重復第一步。
  2. 更新:更新答案。一般是更新最大值/最小值。
  3. 出:下標為 i?k+1 的元素離開窗口,更新相關統計量,為下一個循環做準備。

不定長滑窗

class Solution {public List<Integer> findAnagrams(String s, String p) {List<Integer> ans = new ArrayList<>();int[] cnt = new int[26]; // 統計 p 的每種字母的出現次數for (char c : p.toCharArray()) {cnt[c - 'a']++; //s中出現就-- 若cnt<0則說明子串c太多 }int left = 0;for (int right = 0; right < s.length(); right++) {int c = s.charAt(right) - 'a';cnt[c]--; // 右端點字母進入窗口while (cnt[c] < 0) { // 字母 c 太多了cnt[s.charAt(left) - 'a']++; // 左端點字母離開窗口left++;}if (right - left + 1 == p.length()) { // s' 和 p 的每種字母的出現次數都相同ans.add(left); // s' 左端點下標加入答案}}return ans;}
}

代碼實現時,可以把 cntS 和 cntP 合并成一個 cnt:

  • 對于 p 的字母 c,把 cnt[p] ++

  • 對于 s’ 的字母 c,把 cnt[c] –

  • 如果 cnt[c]<0,說明窗口中的字母 c 的個數比 p 的多,右移左端點。

D3

560. 和為 K 的子數組

560. 和為 K 的子數組

暴力

遍歷得到所有子串并求和 篩選出符合條件的

class Solution {public int subarraySum(int[] nums, int k) {int ans = 0;int n = nums.length;for(int i = 0;i < n;i++){  //列舉每個元素當子串結尾的情況int sum = 0;for(int j = i;j >= 0;j--){  //求所有以這個子串為結尾的和sum += nums[j];if(sum == k)ans++;}}return ans;}
}
前綴和+哈希表

前綴和pre[i]=pre[i?1]+nums[i]

[j…i] 這個子數組和為 k 這個條件我們可以轉化為pre[i]?pre[j?1]==k

簡單移項可得符合條件的下標 j 需要滿足

pre[j?1]==pre[i]?k

class Solution {public int subarraySum(int[] nums, int k) {int ans = 0,pre = 0;int n = nums.length;HashMap<Integer,Integer>mp = new HashMap<>();mp.put(0,1);for(int i = 0;i < n;i++){pre += nums[i];if(mp.containsKey(pre - k)){ans += mp.get(pre - k);}mp.put(pre,mp.getOrDefault(pre,0) + 1);}return ans;}
}

D4

239. 滑動窗口最大值

239. 滑動窗口最大值

單調隊列

單調隊列套路

  1. 右邊入(元素進入隊尾,同時維護隊列單調性
  2. 左邊出(元素離開隊首
  3. 記錄/維護答案(根據隊首
class Solution {public int[] maxSlidingWindow(int[] nums, int k) {int n = nums.length;int[] ans = new int[n - k + 1]; // 窗口個數Deque<Integer> q = new ArrayDeque<>(); // 更快的寫法見【Java 數組】for (int i = 0; i < n; i++) {// 1. 右邊入while (!q.isEmpty() && nums[q.getLast()] <= nums[i]) {q.removeLast(); // 維護 q 的單調性}q.addLast(i); // 注意保存的是下標,這樣下面可以判斷隊首是否離開窗口// 2. 左邊出int left = i - k + 1; // 窗口左端點if (q.getFirst() < left) { // 隊首離開窗口q.removeFirst();}// 3. 在窗口左端點處記錄答案if (left >= 0) {// 由于隊首到隊尾單調遞減,所以窗口最大值就在隊首ans[left] = nums[q.getFirst()];}}return ans;}
}

D5

76. 最小覆蓋子串

76. 最小覆蓋子串

class Solution {public String minWindow(String S, String t) {int[] cntS = new int[128]; // s 子串字母的出現次數int[] cntT = new int[128]; // t 中字母的出現次數for (char c : t.toCharArray()) {cntT[c]++;}char[] s = S.toCharArray();int m = s.length;int ansLeft = -1;int ansRight = m;int left = 0;for (int right = 0; right < m; right++) { // 移動子串右端點cntS[s[right]]++; // 右端點字母移入子串 如果 s[right] 是一個 char 類型的字符,它會被自動轉換成對應的 ASCII/Unicode 數值(int),然后作為數組下標使用while (isCovered(cntS, cntT)) { // 涵蓋if (right - left < ansRight - ansLeft) { // 找到更短的子串ansLeft = left; // 記錄此時的左右端點ansRight = right;}cntS[s[left]]--; // 左端點字母移出子串left++;}}return ansLeft < 0 ? "" : S.substring(ansLeft, ansRight + 1);}private boolean isCovered(int[] cntS, int[] cntT) {for (int i = 'A'; i <= 'Z'; i++) {if (cntS[i] < cntT[i]) {return false;}}for (int i = 'a'; i <= 'z'; i++) {if (cntS[i] < cntT[i]) {return false;}}return true;}
}

D6

53. 最大子數組和

53. 最大子數組和

貪心

若指針所指當前元素之前的和小于0,則丟棄當前元素之前的數列

class Solution {public int maxSubArray(int[] nums) {int pre = 0, ans = nums[0];for (int x : nums) {if(pre < 0){pre = x;}else{pre += x;}ans = Math.max(pre,ans);}return ans;}
}
動態規劃

考慮 nums[i] 單獨成為一段還是加入 f(i?1) 對應的那一段,這取決于 nums[i] 和f(i?1)+nums[i] 的大小

class Solution {public int maxSubArray(int[] nums) {int pre = 0, maxAns = nums[0];for (int x : nums) {pre = Math.max(pre + x, x);maxAns = Math.max(maxAns, pre);}return maxAns;}
}

D7

56. 合并區間

56. 合并區間

一開始想到三種區間關系,覆蓋,重疊,相離,不知道怎么把合并的區間添加到ans中

其實不用分出三種區間關系,直接判斷能否合并就行,即前一個的right和后一個left的關系:

  • q_left <= p_right 可以合并
  • q_left > p_right 不可以合并

對于最后將合并好的區間添加的ans里也可以簡單化:

  • 可合并:添加前一個區間p進ans 修改p_right為q_right(如果q_right更大的話)
  • 不可合并:直接將該區間加入
    在這里插入圖片描述
class Solution {public int[][] merge(int[][] intervals) {Arrays.sort(intervals, (p, q) -> p[0] - q[0]); // 按照左端點從小到大排序List<int[]> ans = new ArrayList<>(); //不知道最后結果大小 沒法用二維數組for (int[] p : intervals) {int m = ans.size();if (m > 0 && p[0] <= ans.get(m - 1)[1]) { // 可以合并ans.get(m - 1)[1] = Math.max(ans.get(m - 1)[1], p[1]); // 更新右端點最大值} else { // 不相交,無法合并ans.add(p);}}return ans.toArray(new int[ans.size()][]);}
}

return ans.toArray(new int[ans.size()][]);

作用是:List<int[]> 轉換為 int[][](二維數組)并返回

為什么要寫這一行?

  • 函數的返回類型是 int[][](二維數組)
  • 但我們使用 List<int[]> 來動態存儲合并后的區間(因為 List 可以隨時 add,而數組大小固定)

所以,在最后必須把 List 轉成 int[][] 才能返回。

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

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

相關文章

vue2純前端對接海康威視攝像頭實現實時視頻預覽

vue2純前端對接海康威視攝像頭實現實時視頻預覽一、環境準備二、代碼集成1.1 準備webrtcstreamer.js&#xff0c;粘貼即用&#xff0c;不用做任何修改1.2 封裝視頻組件&#xff0c;在需要視頻的地方引入此封裝的視頻組件即可&#xff0c;也是粘貼即用&#xff0c;注意其中impor…

Android 設置禁止截圖和禁止長截圖

1.禁止截圖 在 Activity 代碼中 , 可以在調用 setContentView 函數之前 ,為 Window 窗口對象 設置 LayoutParams.FLAG_SECURE 標志位 , 可以禁止對本界面進行截屏 ,Window 窗口對象 , 可通過 getWindow 方法獲取 ,核心代碼如下 :getWindow().setFlags(LayoutParams.FLAG_SECUR…

AR 巡檢在工業的應用|阿法龍XR云平臺

AR 巡檢的應用覆蓋電力、石油化工、智能制造、軌道交通、冶金等對設備可靠性和安全性要求極高的行業&#xff0c;具體場景包括&#xff1a;電力行業變電站內設備的狀態檢查&#xff1a;通過 AR 眼鏡掃描設備&#xff0c;實時顯示設備額定參數、歷史故障記錄、實時傳感器數據&am…

【C++】STL詳解(七)—stack和queue的介紹及使用

? 堅持用 清晰易懂的圖解 代碼語言&#xff0c; 讓每個知識點都 簡單直觀 &#xff01; &#x1f680; 個人主頁 &#xff1a;不呆頭 CSDN &#x1f331; 代碼倉庫 &#xff1a;不呆頭 Gitee &#x1f4cc; 專欄系列 &#xff1a; &#x1f4d6; 《C語言》&#x1f9e9; 《…

深度學習周報(9.8~9.14)

目錄 摘要 Abstract 1 LSTM相關網絡總結與對比 1.1 理論總結 1.2 代碼運行對比 2 量子計算入門 3 總結 摘要 本周首先總結了LSTM、Bi-LSTM與GRU的區別與優缺點&#xff0c;對比了三者實戰的代碼與效果&#xff0c;還另外拓展了一些循環神經網絡變體&#xff08;包括窺視…

Quat 四元數庫使用教程:應用場景概述

基礎概念 四元數是一個包含四個元素的數組 [x, y, z, w]&#xff0c;其中 x,y,z表示虛部&#xff0c;w 表示實部。單位四元數常用于表示3D空間中的旋轉。 1. 創建和初始化函數 create() - 創建單位四元數 應用場景&#xff1a;初始化一個新的四元數對象&#xff0c;通常作為其他…

【Java后端】Spring Boot 多模塊項目實戰:從零搭建父工程與子模塊

如何用 Spring Boot 搭建一個父工程 (Parent Project)&#xff0c;并在其中包含多個子模塊 (Module)&#xff0c;適合企業級項目或者需要分模塊管理的場景。Spring Boot 多模塊項目實戰&#xff1a;從零搭建父工程與子模塊在日常開發中&#xff0c;我們經常會遇到這樣的需求&am…

企業級AI會議系統技術實現:快鷺如何用AI重構會議全流程

摘要 本文深度解析快鷺AI會議系統的核心技術架構&#xff0c;重點探討其在語音識別、自然語言處理、數據集成和安全防護等方面的技術實現。通過對比傳統會議系統的技術痛點&#xff0c;分析快鷺AI如何通過技術創新實現會議籌備時間減少67%、數據調取速度提升100倍的顯著效果。…

【CSS學習筆記3】css特性

1css三大特性 1.1層疊性&#xff1a;就近原則&#xff0c;最新定義的樣式 1.2繼承性&#xff1a;子標簽集成父標簽的樣式&#xff0c;如文本和字號 行高的繼承&#xff1a;不加單位指的是當前文字大小的倍數 body {font: 12px/1.5 Microsoft YaHei;color: #be1313;} div {…

[C語言]常見排序算法①

1.排序的概念及常見的排序算法排序在咱們日常生活中十分的常見&#xff0c;就好比是網上購物的時候通常能夠選擇按照什么排序&#xff0c;比如價格、評論數量、銷量等。那么接下來咱們就來了解一些關于排序的概念。排序&#xff1a;所謂排序&#xff0c;就是使一串記錄&#xf…

文獻閱讀筆記:RS電子戰測試與測量技術文檔

信息來源&#xff1a;羅德與施瓦茨&#xff08;Rohde & Schwarz&#xff09;公司關于電子戰&#xff08;Electronic Warfare, EW&#xff09;測試與測量解決方案專業技術文檔。 該文檔由臺灣地區應用工程師Mike Wu撰寫&#xff0c;核心圍繞電子戰基礎、雷達系統、實戰應用及…

別再糾結 Postman 和 Apifox 了!這款開源神器讓 API 測試更簡單

別再糾結 Postman 和 Apifox 了&#xff01;這款開源神器讓 API 測試更簡單&#x1f525; 作為一名開發者&#xff0c;你是否還在為選擇 API 測試工具而糾結&#xff1f;Postman 太重、Apifox 要聯網、付費功能限制多&#xff1f;今天給大家推薦一款完全免費的開源替代方案 ——…

微調神器LLaMA-Factory官方保姆級教程來了,從環境搭建到模型訓練評估全覆蓋

1. 項目背景 開源大模型如LLaMA&#xff0c;Qwen&#xff0c;Baichuan等主要都是使用通用數據進行訓練而來&#xff0c;其對于不同下游的使用場景和垂直領域的效果有待進一步提升&#xff0c;衍生出了微調訓練相關的需求&#xff0c;包含預訓練&#xff08;pt&#xff09;&…

創建其他服務器賬號

? 在 /home74 下創建新用戶的完整步驟1. 創建用戶并指定 home 目錄和 shellsudo useradd -m -d /home74/USERNAME -s /bin/bash USERNAME-m&#xff1a;自動創建目錄并復制 /etc/skel 默認配置文件&#xff08;.bashrc 等&#xff09;。-d&#xff1a;指定用戶 home 路徑&…

【WebGIS】Vue3使用 VueLeaflet + 天地圖 搭建地圖可視化平臺(基礎用法)

初始化 創建項目 nodejs 18.0.6npm 9.5.1 引入地圖服務 VueLeaflet GitHub - vue-leaflet/vue-leaflet&#xff1a; vue-leaflet 與 vue3 兼容 Vue Leaflet (vue2-leaflet) package.josn安裝版本 直接添加四個依賴 {// ..."scripts": {// ...},"depen…

OpenCV 開發 -- 圖像閾值處理

文章目錄[toc]1 基本概念2 簡單閾值處理cv2.threshold3 自適應閾值處理cv2.adaptiveThreshold更多精彩內容&#x1f449;內容導航 &#x1f448;&#x1f449;OpenCV開發 &#x1f448;1 基本概念 圖像閾值處理&#xff08;Thresholding&#xff09;是圖像處理中的一種基本技術…

單串口服務器-工業級串口聯網解決方案

在工業自動化、智能電網、環境監測等領域&#xff0c;傳統串口設備&#xff08;如PLC、傳感器、儀表等&#xff09;的網絡化升級需求日益增長。博為智能單串口服務器憑借高性能硬件架構、多協議支持和工業級可靠性&#xff0c;為RS485設備提供穩定、高效的TCP/IP網絡接入能力&a…

第 9 篇:深入淺出學 Java 語言(JDK8 版)—— 吃透泛型機制,筑牢 Java 類型安全防線

簡介&#xff1a;聚焦 Java 泛型這一“類型安全保障”核心技術&#xff0c;從泛型解決的核心痛點&#xff08;非泛型代碼的運行時類型錯誤、強制類型轉換冗余&#xff09;切入&#xff0c;詳解泛型的本質&#xff08;參數化類型&#xff09;、核心用法&#xff08;泛型類/接口/…

MySQL和Redis的數據一致性問題與業界常見解法

一、為什么會出現數據不一致&#xff1f; 根本原因在于&#xff1a;這是一個涉及兩個獨立存儲系統的數據更新操作&#xff0c;它無法被包裝成一個原子操作&#xff08;分布式事務&#xff09;。更新數據庫和更新緩存是兩個獨立的步驟&#xff0c;無論在代碼中如何排列這兩個步驟…

coolshell文章閱讀摘抄

coolshell文章閱讀摘抄打好基礎學好英語限制你的不是其它人&#xff0c;也不是環境&#xff0c;而是自己Java打好基礎 程序語言&#xff1a;語言的原理&#xff0c;類庫的實現&#xff0c;編程技術&#xff08;并發、異步等&#xff09;&#xff0c;編程范式&#xff0c;設計模…