目錄
1、演算法框架
2、leetcode76.最小覆蓋子串
3、leetcode567.字串的排列
4、leetcode438.找到字串中所有字母異位詞
5、leetcode3.無重複字元的最長子串
int left = 0, right = 0;
while (right < s.size())
}
這個演算法技巧的時間複雜度是 o(n),比字串暴力演算法要高效得多。演算法的思路不難,難的是各種細節問題。比如說如何向視窗中新增新元素,如何縮小視窗,在視窗滑動的哪個階段更新結果。即便你明白了這些細節,也容易出 bug,找 bug 還不知道怎麼找,真的挺讓人心煩的。完整演算法框架如下:
/* 滑動視窗演算法框架 */
void slidingwindow(string s, string t)
int left = 0, right = 0;
int valid = 0;
while (right < s.size())
}}
其中兩處 ... 表示的更新視窗資料的地方,到時候你直接往裡面填就行了。而且,這兩個 ... 處的操作分別是右移和左移視窗更新操作,操作是完全對稱的。
給你乙個字串 s、乙個字串 t,請在字串 s 裡面找出:包含 t 所有字元的最小子串。
示例:
輸入: s = "adobecodebanc", t = "abc"
輸出: "banc"
說明:1、如果 s 中不存這樣的子串,則返回空字串""
。2、如果 s 中存在這樣的子串,我們保證它是唯一的答案。
演算法:
1、用hashmap表快取文字串 s、模式串 t 的內容,用乙個變數 curvaildcnt 來表示兩個表中字元匹配的個數。
2、首先用 checkmap 記錄t中的所有字元(key)及其個數(value)
3、向右滑動視窗 right++,當出現 checkmap中的字元 ch 時,需要用 slidewinmap 儲存,
判斷該字元 ch 的個數是否已經和 checkmap 中的相等,相等則計數curvaildcnt++;
4、當 slidewinmap 中所有的字元均以匹配 checkmap 中的字元,即 curvaildcnt == check.keyset().size(),
對於表中任一字元均有slidewinmap.get(ch) >= checkmap.get(ch),此時滿足條件,開始迴圈視窗的左側。
4.1、更新視窗範圍,左右側邊界
4.2、從左側收縮視窗left++,當出現匹配字元 ch 時,需要從滑動視窗中減去其個數,當 ch 的個數不在匹配時則需要將
curvaildcnt--,表示此字元不在匹配,下一步需要繼續向右增大滑動視窗。
4.3、不斷收縮左側視窗直到視窗不能完全匹配模式串為止。
5、視窗整個滑動過程模式串 checkmap 不動;
通過乙個變數 curvaildcnt 來記錄表中字元的匹配個數;
curvaildcnt == checkmap.keyset().size() 全匹配收縮左側視窗,直到不匹配;
curvaildcnt < checkmap.keyset().size() 不匹配擴充套件右側視窗,直到匹配
只有在模式串checkmap**現的字元才向滑動視窗slidewinmap表中的新增、刪除;
判斷字元是否相等 == 要將取出的integer型別轉換成intvalue(),因為integer不能隨意使用 == ,其表示的範圍為-128~127。
public string minwindow(string s, string t)
map check = new hashmap<>();
map window = new hashmap<>();
int curvaildcnt = 0;
for(int i = 0; i < t.length(); i++)
int left = 0,right = 0;
int start = -1,minlen = s.length() + 1;
while(right < s.length())
}while(curvaildcnt == check.keyset().size())
char delch = s.charat(left);
left++;
if(check.containskey(delch))
window.replace(delch,window.get(delch) - 1);}}
} if(start == -1)else
}
給定兩個字串s1和s2,寫乙個函式來判斷s2是否包含s1的排列。換句話說,第乙個字串的排列之一是第二個字串的子串。
示例1:
輸入: s1 = "ab" s2 = "eidbaooo"
輸出: true
解釋: s2 包含 s1 的排列之一 ("ba").
示例2:
輸入: s1= "ab" s2 = "eidboaoo"
輸出: false
注意:1、輸入的字串只包含小寫字母;2、兩個字串的長度都在 [1, 10,000] 之間
演算法:1、和leetcode76 完全一致,
2、所不同的是當滑動視窗中 window 的字元和 check 中完全一致且視窗的長度也和待匹配子串長度相等,
即可判定此時的視窗為子串的全排列,返回 true,其它所有場景均為 false
...
while(curvaildcnt == check.keyset().size())
...return false;
}
給定乙個字串 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" 的字母異位詞。
演算法:
1、和leetcode567 完全一致,
2、所不同的是當滑動視窗中 window 的字元和 check 中完全一致且視窗的長度也和待匹配子串長度相等,
即可判定此時的視窗為子串的全排列(字母異位詞),儲存left到list,最後返回list即可。
...
while(curvaildcnt == check.keyset().size())
...return list;
}
給定乙個字串,請你找出其中不含有重複字元的最長子串的長度。
示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 因為無重複字元的最長子串是 "abc",所以其長度為 3。
示例 2:
輸入: "bbbbb"
輸出: 1
解釋: 因為無重複字元的最長子串是 "b",所以其長度為 1。
示例 3:
輸入: "pwwkew"
輸出: 3
解釋: 因為無重複字元的最長子串是 "wke",所以其長度為 3。
請注意,你的答案必須是 子串 的長度,"pwke" 是乙個子串行,不是子串。
演算法:
1、僅用乙個hashmap用於記錄滑動視窗中的字元,
2、視窗不斷向右新增新字元 ch,當字元ch出現重複時,
2.1、獲取此時視窗長度並更新最大長度,
2.2、從左收縮視窗將重複字元 ch 剔除
3、將新增字元 ch 新增到表中
4、注意長度就算
public int lengthoflongestsubstring(string s)
window.put(ch,1);
right++;
} return math.max(max,right-left);
}
APT扒了誰的褲子
0 序言 在安全行業渾渾噩噩地浪蕩多年以後,對這個我耐以生存的行業似乎有了一點清晰地認識,而似乎又只是在荒謬中完成又一次的南柯一夢。夢隨心生,心隨境公升,終日流連於摳腳大叔的茫茫滄海,經歷了從人體工學到巧克力鍵盤的時代變遷,我還能做點啥呢!如果說當前安全行業最大的對手是誰,毫無懸念,那就是apt的資...
滑動視窗演算法
我們學習過計算機網路都知道為了避免擁塞發生,在網路傳輸時有滑動視窗協議控制傳輸時流量。該協議允許傳送方在停止並等待確認前傳送多個資料分組。由於傳送方不必每發乙個分組就停下來等待確認,因此該協議可以加速資料的傳輸,提高網路吞吐量。這個跟我們今天說的滑動視窗演算法是乙個原理。該演算法的作用就是將我們多層...
滑動視窗演算法
在letecode程式設計中經常會碰到一類尋找最長序列的問題,這個時候都可以採用滑動視窗的演算法 滑動視窗就是控制乙個雙指標left,right,沒有達到極限條件的時候right指標,操作臨界條件 就讓left指標,然後更新這個最長序列。比如下面的的問題 問題一 給你兩個長度相同的字串,s 和 t。...