LeetCode 第 3 號問題:無重複字符的最長子串

本文首發於公衆號「五分鐘學算法」,是圖解 LeetCode 系列文章之一。java

我的網站:www.cxyxiaowu.comc++

題目來源於 LeetCode 上第 3 號問題:無重複字符的最長子串。題目難度爲 Medium,目前經過率爲 29.0% 。git

題目描述

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

示例 1:算法

輸入: "abcabcbb"
輸出: 3 
解釋: 由於無重複字符的最長子串是 "abc",因此其長度爲 3複製代碼

題目解析

創建一個256位大小的整型數組 freg ,用來創建字符和其出現位置之間的映射。數組

維護一個滑動窗口,窗口內的都是沒有重複的字符,去儘量的擴大窗口的大小,窗口不停的向右滑動。動畫

  • (1)若是當前遍歷到的字符從未出現過,那麼直接擴大右邊界;
  • (2)若是當前遍歷到的字符出現過,則縮小窗口(左邊索引向右移動),而後繼續觀察當前遍歷到的字符;
  • (3)重複(1)(2),直到左邊索引沒法再移動;
  • (4)維護一個結果res,每次用出現過的窗口大小來更新結果 res,最後返回 res 獲取結果。

動畫描述

動畫描述

代碼實現

// 滑動窗口
// 時間複雜度: O(len(s))
// 空間複雜度: O(len(charset))
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int freq[256] = {0};
        int l = 0, r = -1; //滑動窗口爲s[l...r]
        int res = 0;
        // 整個循環從 l == 0; r == -1 這個空窗口開始
        // 到l == s.size(); r == s.size()-1 這個空窗口截止
        // 在每次循環裏逐漸改變窗口, 維護freq, 並記錄當前窗口中是否找到了一個新的最優值
        while(l < s.size()){
            if(r + 1 < s.size() && freq[s[r+1]] == 0){
                r++;
                freq[s[r]]++;
            }else {   //r已經到頭 || freq[s[r+1]] == 1
                freq[s[l]]--;
                l++;
            }
            res = max(res, r-l+1);
        }
        return res;
    }
};
複製代碼
相關文章
相關標籤/搜索