力扣第3題-Swift題解:無重復(fù)字符的最長子串

經(jīng)典雙指針

題目描述

給定一個字符串 s 挽荠,請你找出其中不含有重復(fù)字符的 最長子串 的長度。

示例 1

輸入: s = "abcabcbb"
輸出: 3
解釋: 因為無重復(fù)字符的最長子串是 "abc"漠另,所以其長度為 3跃赚。

示例 2

輸入: s = "bbbbb"
輸出: 1
解釋: 因為無重復(fù)字符的最長子串是 "b",所以其長度為 1纬傲。

示例 3

輸入: s = "pwwkew"
輸出: 3
解釋: 因為無重復(fù)字符的最長子串是 "wke",所以其長度為 3算墨。 請注意领猾,你的答案必須是 子串 的長度,"pwke" 是一個子序列摔竿,不是子串。

示例 4

輸入: s = ""
輸出: 0

提示

  • 0 <= s.length <= 5 * 100,000
  • s 由英文字母熬苍、數(shù)字袁翁、符號和空格組成

原題目鏈接https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

分析

暴力解法(一般通不過)

這個問題的第一個考慮的直接解法是通過兩個for循環(huán)進(jìn)行暴力求解。第一個for循環(huán)i標(biāo)記無重復(fù)子串的起點柄驻,第二個for循環(huán)j標(biāo)記子串的末尾焙压。通過判斷字符串s[i..j]是否是無重復(fù)子串,并和當(dāng)前最長記錄比較來完成算法涯曲。該方案的時間復(fù)雜度是O(n^2)。

但是這個方案在本問題中是不可行的拨黔,因為問題規(guī)模是0 <= s.length <= 5 * 100,000绰沥,如果采用O(n^2)復(fù)雜度基本會超時贺待,并且這也不是最優(yōu)復(fù)雜度态兴。

O(n)雙指針解法

考慮到第一個思路里,用ij分別標(biāo)記字符串的某段起始和終止位置,遍歷整個數(shù)組甜刻,最終得出數(shù)組的最長無重復(fù)子串的長度值。

那么可以把思路調(diào)整為傻铣,讓原先的兩個循環(huán)改成一個循環(huán)祥绞,只掃描一遍數(shù)組即可完成所有無重復(fù)子串的查找。

基本思路原則是這樣的:

  1. 給定兩個字符串索引ij蜕径,且j始終大于i
  2. 每次循環(huán)保證字符串子串s[i..<j]始終為一個無重復(fù)子串梦染。
  3. 始終保證循環(huán)過程中朴皆,i在需要調(diào)整時往終點移動一或者若干位,j往終點移動一位遂铡。
  4. 當(dāng)j移動到字符串末尾時,算法結(jié)束伪货。
  5. 保證循環(huán)結(jié)束時珠增,算法能找到所有的無重復(fù)字子串。

為此蒂教,我們用非形式化的循環(huán)不變式來描述一下該算法的執(zhí)行。

首先是初始化懊悯,當(dāng)i = 0j = 1時,由于s[i..<j]只有一個字符s[0]桃焕,單個字符肯定是一個無重復(fù)子串捧毛。

接下來,我們假設(shè)s[i..<j]是一個無重復(fù)子串呀忧。那么接下去我們要檢查的情形是。

  1. 當(dāng)s[j]所包含的字符在s[i..<j]中并不存在時胰坟,則s[i..<j+1]必然也是無重復(fù)子串泞辐。
  2. 當(dāng)s[j]所包含的字符在s[i..<j]中存在時新锈,假定存在的沖突位置為k,則s[k] == s[j]落午,則s[k+1..<j+1]是新的待掃描的無重復(fù)子串瑰煎。

當(dāng)j為字符串最后一個字符時撇吞,我們已經(jīng)掃描了所有無重復(fù)子串。

那么牍颈,算法在執(zhí)行過程中只要不斷的保存最大的無重復(fù)子串長度即可。

這里就存在一個問題讥蔽,當(dāng)已知s[i..<j]為無重復(fù)子串時画机,我們?nèi)绾沃?code>s[j]的字符在s[i..<j]中存不存在?

留意問題的輸入范圍步氏,我們看到

`s` 由英文字母、數(shù)字芋类、符號和空格組成

由于s 由英文字母、數(shù)字侯繁、符號和空格組成,那就意味著字符串的內(nèi)容是有ascii字符組成丽焊,我們完全可以用一個容量為128的數(shù)組來保存每個字符的位置信息咕别。

具體來講就是,我們用數(shù)組cache保存字符的ascii碼在字符串的最近一次掃描索引信息顷级,舉例來說确垫,就是當(dāng)掃描字符串abc的時候,c在位置2翔冀,那么有cache[c.ascii] = 2披泪。

注:ascii編碼為8位,所以容量僅為128控硼。

swift題解源碼及注釋

class Solution {
    func lengthOfLongestSubstring(_ s: String) -> Int {
        // 算法邊界不包含空字符串艾少,判定返回
        guard !s.isEmpty else { return 0 }

        let cs = s.cString(using: .ascii)!
        let len = strlen(cs)

        // 初始化i和j
        var i = 0
        var j = 1
        
        // cache存放遍歷字符的位置
        var cache: [Int] = Array(repeating: -1, count: 128)
        var m = j - i
        // cache保存著第一個字符的位置
        cache[Int(cs[i])] = i
        while j < len {
            let k = cache[Int(cs[j])]
            if k >= i {
                // 當(dāng)cache保存的字符位置在范圍內(nèi),說明出現(xiàn)字符沖突
                // 調(diào)整 i 讓它往前跳
                i = k + 1
            }
            cache[Int(cs[j])] = j
            j += 1
            // i被調(diào)整過后幔妨,或者沒有沖突字符谍椅,新子串也是無重復(fù)子串
            m = max(m, j-i)
        }
        return m
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市锁施,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沾谜,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件婚温,死亡現(xiàn)場離奇詭異媳否,居然都是意外死亡,警方通過查閱死者的電腦和手機力图,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門掺逼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赘那,你說我怎么就攤上這事氯质。” “怎么了闻察?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵辕漂,是天一觀的道長。 經(jīng)常有香客問我钮热,道長,這世上最難降的妖魔是什么飒责? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任仆潮,我火速辦了婚禮,結(jié)果婚禮上拾并,老公的妹妹穿的比我還像新娘。我一直安慰自己嗅义,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布蝙眶。 她就那樣靜靜地躺著褪那,像睡著了一般。 火紅的嫁衣襯著肌膚如雪博敬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天收恢,我揣著相機與錄音祭往,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛沛鸵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疾捍,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼栏妖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了宛裕?” 一聲冷哼從身側(cè)響起论泛,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岩榆,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體勇边,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡粒褒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谊囚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片执赡。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖沙合,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绊率,我是刑警寧澤究履,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站最仑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏欲芹。R本人自食惡果不足惜吟吝,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浙宜。 院中可真熱鬧蛹磺,春花似錦、人聲如沸称开。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至臭觉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝠筑,已是汗流浹背揩懒。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留臣镣,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓忆某,卻偏偏與公主長得像阔蛉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子棒坏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容