-
題目連結
-
解題思路
- 求最小子串問題,第一時間,想「以i開頭的結果是什麼」,求出所有的結果,最優的便是;或者「以i結尾的結果是什麼」,求出所有的結果,最優的便是
- 這個題使用「以i開頭的結果是什麼」,假設是
[i, j]
然後再求i+1的結果時,我們發現,只需要把i位置的字元去掉,就可以知道是否滿足結果,如果不滿足,我們可以直接把j往後接著找。有點像動態規劃的思想,我知道了dp[i]
,然後dp[i + 1]
就可以利用dp[i]
的結果,快速得到。 - 其實這個題是一個「滑動視窗」的問題。i開頭,滑到j,也就是
[i, j]
就是i的結果,然後把i移除視窗,如果仍然滿足結果,那i+1的結果就是[i + 1, j]
,如果不滿足,j再右移,就是滑動視窗的做法。 - 一些細節
- 1️⃣怎麼知道「j滑到哪裡才滿足」?可以用一個map,key就是某個字元,value就是該字元需要的次數。假設一個map,有
map['a'] = 2
,a字元需要2次。當遇到a之後,減減,當a減到0的時候,我們就能知道,a這個字元滿足了,所以我們還需要用一個變數count
記錄,有幾個字元已經滿足了。假設map的大小是5,就說明,一共有5種字元,當count == 5
時,就說明全部滿足了。 - 2️⃣得到i的結果
[i, j]
後,怎麼把i移除?如果i在map裡,現在i被移除了,所以map中對應的字元要++。 - 那我怎麼知道把i移除之後,i+1是否滿足呢?還是
count
變數,當移除i,i對應的字元在map中,map就要++,如果++後,大於0了,說明,不滿足了。所以,這裡又有一個問題,1️⃣中,遇到map中的字元,就要減減,減到0後還要減嗎?要減!因為i移除之後,map要加加,如果此時還是小於等於0,那就說明i+1還是滿足條件的。 - 總結一下:
- 當遍歷到的字元,是需要的,map中對應的字元就要減減,如果減減後,等於0了,那麼
count++
,當count==5
時,就說明滿足條件了 - 當移除i時,如果在map中,那麼對應的字元就要加加,如果加加後,大於1了,那麼
count--
,此時j就要往右滑了。
- 當遍歷到的字元,是需要的,map中對應的字元就要減減,如果減減後,等於0了,那麼
- 1️⃣怎麼知道「j滑到哪裡才滿足」?可以用一個map,key就是某個字元,value就是該字元需要的次數。假設一個map,有
-
程式碼
class Solution { public: string minWindow(string s, string t) { int ans_len = INT32_MAX; // 答案的長度 int ans_index = -1; // 答案的開始下標 unordered_map<char, int> need; // 需要滿足的字元 int count = 0; // 構造需要滿足的字元 for (auto &it : t) { need[it]++; } int n = s.size(); int j = -1; // 視窗右邊界 for (int i = 0; i < n; ++i) { // 以i開頭的答案是什麼? // 將i - 1移出視窗 if (i - 1 >= 0 && need.count(s[i - 1]) != 0) { if (need[s[i - 1]]++ == 0) { // 等同於need[s[i - 1]]++; if (need[s[i - 1]] > 0) count--; } } while(j + 1 < n && count != need.size()) { // 如果不滿足條件 j要往右擴 j++; if (need.count(s[j]) != 0) { if (need[s[j]]-- == 1) { // 等同於need[s[j]]--; if (need[s[j]] == 0) count++; } } } if (count == need.size()) { // 滿足要求 if (j - i + 1 < ans_len) { // 如果能更新 ans_len = j - i + 1; ans_index = i; } } else { // j都越界了 還沒滿足要求 說明滿足不了了 後面的也滿足不了了 break; } } if (ans_index == -1) { // 沒有找到 return ""; } return s.substr(ans_index, ans_len); } };
76. 最小覆蓋子串
相關文章
- 76.最小覆蓋子串 Golang實現Golang
- Q13 LeetCode76 最小覆蓋子串LeetCode
- 最小圓覆蓋
- 最大匹配、最小頂點覆蓋、最大獨立集、最小路徑覆蓋(轉)(再轉)
- 最小路徑可重複點覆蓋
- 1.1.3.3 最小割之最小權覆蓋集、最大權獨立集
- 樹上最小點覆蓋的一類問題
- BZOJ1927: [Sdoi2010]星際競速(最小費用最大流 最小路徑覆蓋)
- 矩形覆蓋
- BZOJ 1185 [HNOI2007]最小矩形覆蓋:凸包 + 旋轉卡殼
- 二分圖最小點覆蓋等於二分圖最大匹配
- 二分圖最小點覆蓋構造方案+König定理證明
- 洛谷OJ:P2764 最小路徑覆蓋問題(網路流)
- Mysql索引覆蓋MySql索引
- 棋盤覆蓋
- 程式碼覆蓋率與測試覆蓋率比較
- 子串位置
- 企業WiFi覆蓋,解決覆蓋四大難題WiFi
- 全球覆蓋 雜湊
- 線段覆蓋(挖
- idea2022.1 檢視單測覆蓋率展示分支覆蓋率Idea
- 最長子串
- 子串查詢
- 2023北航校賽-E 二分圖最小點覆蓋=n-最大獨立集
- MySQL 索引覆蓋(Covering Index)MySql索引Index
- ESLint: 規則配置覆蓋EsLint
- 線段覆蓋問題
- JZ-010-矩形覆蓋
- 【劍指Offer】矩形覆蓋
- 什麼是覆蓋索引?索引
- pHp程式碼覆蓋率PHP
- 棋盤覆蓋問題
- canvas 填充覆蓋描邊Canvas
- php實現矩形覆蓋PHP
- 30串聯所有單詞的子串
- 最長上升子串
- 子串匹配 BF法
- java覆蓋率檢測-jacocoJava