給定一個字符串,找出其中不含有重復字符的 最長子串 的長度(來自LeetCood)


例如:

輸入: "abcabcbb"
輸出: 3 
解釋: 因為無重復字符的最長子串是 "abc",所以其長度為 3。

方法一:
  
     /// <summary>
        /// 給定一個字符串,找出其中不含有重復字符的 最長子串 的長度。
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public int LengthOfLongestSubstring(string str)
        {
            int resLength = 0;
            int strLength = str.Length;
            for (int i = 0; i < strLength; i++)
            {
                for (int j = i + 1; j < strLength; j++)
                {
                    //這里能確定str的所有子串
                    HashSet<string> hashSet = new HashSet<string>();
                    bool isExists = false;
                    for (int z = i; z < j; z++)
                    {
                        string strChildren = str.Substring(z, 1);
                        if (hashSet.Contains(strChildren))
                        {
                            isExists = true;
                            break;
                        }
                        else
                        {
                            hashSet.Add(strChildren);
                        }
                    }
                    if (!isExists)
                    {
                        //這里是不存在相同的才給resLength賦值
                        resLength = Math.Max(resLength, j - i);
                    }
                   
                }
            }
            return resLength;
        }

  方法二:滑動窗口

    在方法一中,我們會反復檢查一個子字符串是否含有有重復的字符,但這是沒有必要的。如果從索引 i 到 j - 1 之間的子字符串sij 已經被檢查為沒有重復字符。我們只需要檢查 s[j] 對應的字符是否已經存在於子字符串 sij 中。

    要檢查一個字符是否已經在子字符串中,我們可以檢查整個子字符串,這將產生一個復雜度為 O(n2) 的算法,但我們可以做得更好。

    通過使用 HashSet 作為滑動窗口,我們可以用 O(1) 的時間來完成對字符是否在當前的子字符串中的檢查。

    滑動窗口是數組/字符串問題中常用的抽象概念。 窗口通常是在數組/字符串中由開始和結束索引定義的一系列元素的集合,即 [i, j)(左閉,右開)。而滑動窗口是可以將兩個邊界向某一方向“滑動”的窗口。例如,我們將 [i, j)向右滑動 11 個元素,則它將變為 [i+1, j+1)(左閉,右開)。

    回到我們的問題,我們使用 HashSet 將字符存儲在當前窗口 [i, j)(最初 j = i)中。 然后我們向右側滑動索引 j,如果它不在 HashSet 中,我們會繼續滑動 j。直到 s[j] 已經存在於 HashSet 中。此時,我們找到的沒有重復字符的最長子字符串將會以索引 i開頭。如果我們對所有的 i 這樣做,就可以得到答案。

   

       public int LengthOfLongestSubstring(string str)
        {
            int resLength = 0;
            int strLength = str.Length;
            int i = 0, j = 0;
            HashSet<string> hashSet = new HashSet<string>();

            while (i < strLength && j < strLength)
            {
                string oneStrJ = str.Substring(j,1);
                if (!hashSet.Contains(oneStrJ))
                {
                    hashSet.Add(oneStrJ);
                    j++;
                    resLength = Math.Max(resLength,j-i);
                }
                else
                {
                    string oneStrI = str.Substring(i, 1);
                    hashSet.Remove(oneStrI);
                    i++;
                }
            }
            return resLength;
        }

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM