1. 程式人生 > >字串最長子串難?滑動視窗拯救你

字串最長子串難?滑動視窗拯救你

題目:leetcode 3. 無重複字元的最長子串

給定一個字串,請你找出其中不含有重複字元的 最長子串 的長度。

示例 1:

輸入: s = "abcabcbb"

輸出: 3 

解釋: 因為無重複字元的最長子串是 "abc",所以其長度為 3。

 

子串:串中任意個連續的字元組成的子序列稱為該串的子串。

解題思路

要求字串的不含有重複字元的最長子串的長度,只需要先找到最長子串然後再求其長度即可,找最長子串我們可以通過滑動視窗的方法去查詢。

滑動視窗

滑動視窗就是通過不斷調整子序列的 start 和 end 位置,從而獲取滿足要求的結果。

具體操作如下:

  • 假設已經找到一個不含重複字元子串 s[left...right],s[left...right] 表示從字串 s 的下標 left 到 right 的子串。

                 

  • 子串陣列的右邊界 right 向右移,拓展子串長度,以尋找最長子串。

  • 將字元 s[right + 1] 跟子串 s[left...right] 中的每個字元進行比較,如果都不同,則將字元 s[right + 1] 也納入到子串中。

    如果字元 s[right + 1] 跟子串 s[left...right] 中的某個字元相同,則將子串陣列的左邊界 left 右移,刨除 s[left...right] 中的那個重複的字元;

                                                         刨除前

                                                                刨除後

  • left 到 right 這個區間形成一個滑動視窗,為了尋找滿足條件的子串,視窗不停地在向前滑動,記錄子串的長度是否是更長的子串。

     

細節

如何判斷右邊界 right 向右拓展時,其對應的字元和當前找到的子串中無重複字元呢?一個簡單的方法是:設定一個數組記錄 ASCII 碼出現的頻率,這樣當 right 向右拓展時,就可以查詢其對應的字元對應的 ASCII 碼在該陣列中相應的頻率值的多少判斷是否出現了重複字元。

 

Show me the Code

 1 // c 語言
 2 int lengthOfLongestSubstring(char * s){
 3     int res = 0;
 4     int len = strlen(s);
 5     /* 記錄 ASCII 字元在子串中出現的次數 */
 6     int freq[256] = {0};
 7     /* 定義滑動視窗為 s[l...r] */
 8     int l = 0, r = -1;
 9     while (l < len) {
10         /* freq 中不存在該字元,右邊界右移,並將該字元出現的次數記錄在 freq 中 */
11         if (r < len - 1 && freq[s[r + 1]] == 0) {
12             freq[s[++r]]++;
13         /* 右邊界無法拓展,左邊界右移,刨除重複元素,並將此時左邊界對應的字元出現的次數在 freq 的記錄中減一 */
14         } else {
15             freq[s[l++]]--;
16         }
17         /* 當前子串的長度和已找到的最長子串的長度取最大值 */
18         res = fmax(res, r - l + 1);
19     }
20     return res;
21 }
 1 // c++ 語言
 2 int lengthOfLongestSubstring(string s) {
 3     int res = 0;
 4     int len = s.size();
 5     int freq[256] = {0};
 6     int l = 0, r = -1;
 7     while (l < len) {
 8         if (r + 1 < len && freq[s[r + 1]] == 0) {
 9             freq[s[++r]]++;
10         } else {
11             freq[s[l++]]--;
12         }
13         res = max(res, r - l + 1);
14     }
15     return res;
16 }
View Code

更多精彩

關注公眾號 『 TanLiuYi00 』回覆「演算法」,即可獲取經典高清無碼演算法與資料結構相關電子書