演算法-無重複字元的最長子串

zeng沐白發表於2018-07-07

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

示例: 給定 "abcabcbb" ,沒有重複字元的最長子串是 "abc" ,那麼長度就是3。

給定 "bbbbb" ,最長的子串就是 "b" ,長度是1。

給定 "pwwkew" ,最長子串是 "wke" ,長度是3。請注意答案必須是一個子串,"pwke" 是 子序列 而不是子串。

思路:

  1. 從字串第一個元素起,從左到右獲取子串。
  2. 每前進一個字元(下標為j),就在當前子串中查詢是否存在與當前字元重複的字元,如果存在(重複字元的下標為i),那麼能確定一個包含不重複字元的子串,其長度為j - i 對比已儲存的最大長度並把兩者的最大值儲存。
  3. 現在下一個子串的起點為當前重複的字元下標j.重複執行2、3操作,直到最後一個字元。

其實這是滑動視窗的思路。左閉右開。

int lengthOfLongestSubstring(char* s) {
    int len = strlen(s);
    //長度為0 的情況的處理
    if(len == 0) return 0;
    int max = 1;
    int statrIndex = 0;
    for (int i = 1; i < len; i ++) {
        char subStr = s[i];
        for(int j = statrIndex; j <i; j ++)
        {
            char ssubStr = s[j];
            //如果找到重複字串
            if (subStr == ssubStr ) {
                if (max < i  - statrIndex) {
                    max = i  - statrIndex;
                }
                statrIndex = j + 1;
                break;
            }
        }
        //長度沒新增一位,更新最大值
        if (max < i + 1 - statrIndex) {
            max = i + 1 - statrIndex;
        }
    }
    return max;
}
複製程式碼

其他解法:

//每個字元都有唯一字串ASCII的作為唯一標識,這是個技巧性問題。最多256個
int lengthOfLongestSubstring(char* s) {
    //演算法:用book標記出現過的字元的index,用max標記最大長度,用start標記當前不重複開始的index,用num表示當前不重複的個數
    //遍歷陣列,若book[]大於start,說明遇到相同元素,則從其相同處重新計算長度和起始位置
    if(NULL == s)
        return NULL;
    int len=strlen(s);
    int book[255]={0};
    //memset(book,0xff,255*sizeof(int));//將book初始化為-1
    if (0==len)
        return 0;
    int start=0,max=0;//max_start=0;
    int num=0;
    for (int i=0;i<len;i++)
    {
        if(book[s[i]]==0 || book[s[i]]<start+1)
        {
            num++;
            if(num>max)
            {
                //max_start=start;
                max=num;
            }
            book[s[i]]=i+1;
        }
        else
        {
            start=book[s[i]];
            num=i-start+1;
            book[s[i]]=i+1;
        }
    }
    return max;
}
複製程式碼
//寫得好屌啊
int lengthOfLongestSubstring(char* s) {
    int len=0;
    char *end=s,*temp;
    char* addressTable[128]={NULL};
    while(*end){
        temp = addressTable[*end];
        addressTable[*end]=end;
        if(temp>=s){
        len=end-s>len?end-s:len;
        s = temp+1;
        }end++;
    }
    len=end-s>len?end-s:len;
    return len;
}
複製程式碼

小結:這裡又存在查詢問題,可以考慮使用雜湊Map提高效率。

待完善....

相關文章