無重複字符最長字串的滑動窗口結合哈希表解法(註釋詳盡)

這個解法是由leetcode上的jack這名用戶上傳,巧妙的使用了哈希表來縮短執行時間,非常值得學習,但是原作者並沒有將原理和亮點講的很清楚,所以我重新將它梳理了一遍發了出來。

思路:

這個解法是以常規的滑動思想爲基礎,字符串左右各一個指針(left和right),左邊的指針標記的是最近的重複字符(初始值爲0.表示暫無重複字符),然後right指針進行遍歷,若遍歷字符與目前兩指針中間的字符串中字符重複,則將left指針移向該重複字符,right指針繼續向前遍歷,知道遍歷結束爲止,其中沒遍歷一個字符,都進行一次目前字符串長度與最長字符串長度的比較。
        然後根據字符是由ASCII碼錶示的特點,創建一個256個元素的數組,作爲哈希表,用於儲存每一個字符最近出現位置,若未出現過,則爲0,若出現了,則將其位置信息存入(即right的值),若第二次出現,則通過找到對應ASCII碼值,就可知該字符最近一次出現位置,從而完成left指針的移動。

 

代碼:

int lengthOfLongestSubstring(char * s){
    //用於儲存目前最長字串
    int prior = 0;
    //用於定位目前不重複字符串的起始字符左邊一個字符(即最近一個出現重複的字符)
    int left = 0;
    //用數組構建一個哈希表,存儲該字符最近出現位置,若爲0,則表示沒有出現過,並且爲256而不爲128是因爲此處是ASCII擴展字符集
    int dict[256] = {0};
    //目前所遍歷的字符串的位置
    int right = 1;
    //存儲目前字符的ASCII值
    int i;

    while (* s != '\0')
    {
        //獲得目前字符的ASCII值
        i = * s - 0;

        //判斷目前所遍歷字符是否出現過
        if (dict[i] > left)
            //若出現過,則將目前不重複字符串起始位置之前的一位定位到該字符
            left = dict[i];

        //不論是否出現過,都更新該字母對應哈希表的值
        dict[i] = right;

        //判斷目前不重複字符串長度是否比出現過的最長不重複字符串長
        prior = (prior>right-left)? prior : right-left;

        //將指針指向下一個字符
        s++;

        //更新爲接下來要遍歷的字符的位置
        right++;
    }

    return prior;
}

 

發佈了32 篇原創文章 · 獲贊 0 · 訪問量 1227
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章