【LeetCode】4. Longest Substring Without Repeating Characters 最長無重複子串

題目:

            Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.


翻譯:

           找到最長無重複子串,返回長度。


思路:

          打算在以後的博客中,寫上自己的思路、貼上自己的代碼的同時,也分析一下別人的思路和寫法,畢竟自己的算法不一定是最優的。這道題在最開始做的時候,我的想法非常簡單:

          1.若給定字符串爲空,返回0(注意邊界情況);否則轉2。

          2.用tempString來存儲無重複子串,maxSize來記錄最長無重複子串的長度;

             初始化tempString爲給定字符串的第一個字符,maxSize=1;

             從字符串的第2個字符開始,到字符串結束,依次檢測每一個字符是否出現在當前無重複子串中:

            (1) 若這個字符在沒有出現在當前無重複子串中,將該字符加入到當前無重複子串中;

            (2)若這個字符出現在了當前無重複子串中,

                      比較該無重複子串的長度與maxSize的大小,若該無重複子串的長度大於maxSize,更新maxSize爲該無重複子串的長度;

                      更新tempString爲字符串中出現當前字符的下一個字符起始到該字符爲止的子串(這裏說的比較繞口,或不好懂,可以看代碼);

          3.待整個字符串都檢測完畢後,最後判斷一次tempString的長度與maxSize的大小,返回較大的一個。


代碼:

public class Solution {
    public int LengthOfLongestSubstring(string s) {
        if(s=="")
            return 0;
        char[] array=s.ToCharArray();
        string tempString=array[0].ToString();
        int maxSize=1;
        for(int i=1;i<array.Count();i++)
        {
            int index=tempString.IndexOf(array[i]);
            if(index!=-1)//若在tempString中存在這個字符
            {
                if(tempString.Length>maxSize)
                    maxSize=tempString.Length;
                tempString=tempString.Substring(index+1)+array[i].ToString();
            }
            else//若在tempString中不存在這個字符
                tempString+=array[i].ToString();
        }
        if(tempString.Length>maxSize)
            return tempString.Length;
        return maxSize;
    }
}

         在上面的代碼中我應用了額外的空間,包括將字符串轉換成字符數組,以及使用tempString來存儲當前無重複子串,其實都是不必要的,下面這段代碼我使用了C#中的

int string.IndexOf(char value, int startIndex, int count)函數來取代上面代碼中應用到的int string.IndexOf(char value)來查找字符串中是否存在某個字符,於是不需要額外將字符串轉化成字符數組,也不需要使用一個臨時的string變量tempString來存儲當前無重複子串。

        我對上面的代碼進行了稍微的修改,使用startIndex來記錄當前無重複子串的起始位置,count記錄當前無重複子串的長度,maxSize仍然記錄最長無公共子串的長度。即用startIndex和count兩個變量來記錄無重複子串在原字符串中的起始位置和長度的方式來記錄當前無重複子串,而不是單獨使用一個變量。經過這樣的改進後,空間上僅需要三個int類型,時間複雜度爲O(n),速度大大提升。


改進後的代碼:

public class Solution {
    public int LengthOfLongestSubstring(string s) {
        if(s=="")
            return 0;
        int startIndex=0;
        int count=1;
        int maxSize=1;
        for(int i=1;i<s.Length;i++)
        {
            int index=s.IndexOf(s[i],startIndex,count);//從字符串的startIndex下標開始,檢測長度爲count的子串中是否存在s[i],若存在,則返回s[i]在這個字符串中的位置(下標)
            if(index!=-1)//當前無重複子串中存在這個字符
            {
                if(count>maxSize)
                    maxSize=count;
                startIndex=index+1;//產生新的無重複子串,這個無重複子串從index下一個位置開始,到是s[i]結束
                count=i-index;//計算新的無重複子串的長度
            }
            else//將s[i]加入當前無重複子串中
                count++;
        }
        if(count>maxSize)
            return count;
        return maxSize;
    }
}


         

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