刷題之路第三題--Longest Substring Without Repeating Characters
問題簡介:求給定字符串中最長的字符不重復的字符串的長度
問題詳解:
給定一個字符串,尋找給定字符串中包含的最長的字符不重復的字符串的長度
註:答案必須是子字符串,不是子序列
是連續的字符不重復的字符串,不是所有不重復字符
舉例:
1.
輸入: “abcabcbb”
輸出: 3
解釋: 結果是 “abc”, 長度是 3
2.
輸入: “bbbbb”
輸出: 1
解釋: 結果是 “b”,長度是 1
3.
輸入: “pwwkew”
輸出: 3
解釋: 結果是 “wke”,長度是 3
JAVA 實現方法一:笨方法遍歷(第一次愚蠢實現不推薦)
官方實現一 : Brute Force
簡介:
逐個檢查所有子字符串,看它是否沒有重復的字符。
算法:
寫一個方法 boolean allUnique(String substring),如果子字符串中的字符都是唯一的,則返回true,否則返回false.我們可以遍歷給定字符串s的所有可能的子字符串並調用函數allUnique(),如果結果是true,那麽我們更新子字符串的最大長度.
現在讓我們填補缺少的部分:
復雜度分析:
時間復雜度 : 兩層O(n3):main()中兩層遍歷,方法中還有一層遍歷.
空間復雜度 : O(min(n,m)):取決於字符串長度
官方實現二 : Sliding Window
滑動窗口是數組/字符串問題中常用的抽象概念。窗口是數組/字符串中的一系列元素,通常由開始和結束索引定義,即[i,j].
使用HashSet將字符存儲在當前窗口[i,j]中(最初j = i)然後我們將索引jjj向右滑動,如果它不在HashSet中,我們進一步滑動j,這樣做直到 s [j] 已經在HashSet中.此時,我們發現沒有重復字符的子字符串的最大大小以索引i開頭,為所有i執行此操作,會得到答案
復雜度分析;
時間復雜度 : O(n):一層循環
空間復雜度: O(min(m,n))
官方實現三 : Sliding Window Optimized
定義字符到其索引的映射,而不是使用一個集來判斷字符是否存在。,然後我們可以在找到重復的字符時立即跳過字符.
原因是,如果s [j] 在[i,j] 的範圍內具有索引j的重復,我們不會需要一點一點地增加i,我們可以跳過[i,j] 範圍內的所有元素,並讓i直接為j+ 1
還可以假設ASCII 128
以前的實現都沒有對字符串s的字符集進行假設。
如果我們知道charset相當小,我們可以用整數數組替換Map作為直接訪問表。
常用的表有:
int[26] for Letters ‘a’ - ‘z’ or ‘A’ - ‘Z’
int[128] for ASCII
int[256] for Extended ASCII
復雜度分析:
時間復雜度 : O(n).
空間復雜度(HashMap) : O(min(m,n)).
空間復雜度(Table): O(m).
小提示:
String的三種方法 indexOf(),lastIndexOf(),subString()
刷題之路第三題--Longest Substring Without Repeating Characters