1. 程式人生 > >刷題之路第三題--Longest Substring Without Repeating Characters

刷題之路第三題--Longest Substring Without Repeating Characters

force last 分享圖片 center 訪問表 給定 rsquo 滑動 class

問題簡介:求給定字符串中最長的字符不重復的字符串的長度

問題詳解:

給定一個字符串,尋找給定字符串中包含的最長的字符不重復的字符串的長度

註:答案必須是子字符串,不是子序列

是連續的字符不重復的字符串,不是所有不重復字符

舉例:

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