395: Longest Substring with At Least K Repeating Characters

題目鏈接:395

解題思路

對(duì)于substring变姨、subarray這種求子集類的問題谜诫,常用的做法有兩種:一是遞歸,二是滑動(dòng)窗口急膀。

遞歸天生就適合解決這類問題画株,因?yàn)樗褪峭ㄟ^解決“子集”從而來解決“父集”的瀑志。

滑動(dòng)窗口則是由于窗口內(nèi)的所有元素其實(shí)就是一個(gè)“子集”,只不過通過某種具有“單調(diào)性”的策略將策略范圍內(nèi)的子集遍歷了一遍污秆,從而找到答案劈猪。滑動(dòng)窗口相比于遞歸擁有更好的時(shí)間良拼、空間復(fù)雜度战得,但它的使用限制則比遞歸多,只能解決具有“單調(diào)性”策略的問題庸推。

根據(jù)官方題解常侦,似乎可以用滑動(dòng)窗口解決浇冰,但是我沒有理解具體的做法。

而使用遞歸解決問題的時(shí)候聋亡,最重要的是回答三個(gè)問題:

  1. 遞歸函數(shù)的物理意義是什么肘习?
  2. 遞歸的終止條件是什么?
  3. 對(duì)于當(dāng)前層來說坡倔,子問題是什么漂佩?

對(duì)于這道題,也可以通過回答這三個(gè)問題來明確遞歸思路罪塔。

  1. 設(shè)計(jì)的遞歸函數(shù) longestSubstring(s string, k int) int投蝉,它的物理意義即題意:給定一個(gè)字符串s,找到長(zhǎng)度最長(zhǎng)的滿足條件的子字符串征堪,該子字符串的每一種字符都出現(xiàn)了k次以上瘩缆。
  2. 終止條件是:1. s 的長(zhǎng)度小于 k,不存在符合條件的子串佃蚜,返回0庸娱;2. 當(dāng)前 s 即滿足條件,即 s 中每個(gè)字符都出現(xiàn) k 次以上谐算,返回 s 的長(zhǎng)度涌韩。
  3. 將當(dāng)前字符串根據(jù)不符合條件的字符進(jìn)行分割,分割后的不包含非法字符的子串即為新的子問題氯夷,而當(dāng)前問題的答案即為所有子問題的答案的最大值臣樱。

根據(jù)以上分析,可以寫出代碼:

// use recursion
// recursion rule: give a string s, return the longest substring's length that is satisfed

func longestSubstring(s string, k int) int {
    // Base case
    if len(s) < k {
        return 0
    }
    // scan the string, use two maps to record info
    // m1: key: char; val: appearing times
    // valid: record satisfied character, key: char; val: bool
    m1 := make(map[byte]int)
    valid := make(map[byte]bool)
    for i := range s {
        ch := s[i]
        count, ok := m1[ch]
        if !ok {
            m1[ch] = 1
        } else {
            m1[ch] = count + 1
        }
        // 滿足條件了腮考,加入 valid map 中
        if m1[ch] >= k {
            valid[ch] = true
        }
    }
    // all characters are satisfied
    if len(m1) == len(valid) {
        return len(s)
    }
    // use sliding window to discard invalid character and split the string
    // all characters in substring between [left, right) are valid, do dfs on this substring
    left := 0
    right := 0
    maxLength := 0
    for right < len(s) {
        // find left bound
        for left < len(s) && !valid[s[left]] {
            left++
        }
        // refresh right bound
        if right < left {
            right = left
        }
        // find right bound
        for right < len(s) && valid[s[right]] {
            right++
        }
        // record ans
        length := longestSubstring(s[left:right], k)
        maxLength = max(maxLength, length)
        // refresh left bound
        left = right
    }
    return maxLength
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

時(shí)間復(fù)雜度:O(N * 26)雇毫。N為字符串的長(zhǎng)度,26為字符集的個(gè)數(shù)踩蔚,本題中字符為所有小寫字母棚放,即26個(gè)。由于每一次遞歸都能完全去除一種字符(即一種小寫字母)馅闽,因此遞歸最深有26層飘蚯,每一層最多遍歷N個(gè)元素,因此時(shí)間復(fù)雜度是O(N * 26)

空間復(fù)雜度:O(26 * 26)福也。由于最深能夠遞歸26層局骤,每一層又開辟了map,該map最多存26個(gè)鍵值對(duì)暴凑,即一個(gè)map O(26)的空間復(fù)雜度峦甩,因此總共的空間復(fù)雜度是 O(26 * 26)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市现喳,隨后出現(xiàn)的幾起案子凯傲,更是在濱河造成了極大的恐慌犬辰,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冰单,死亡現(xiàn)場(chǎng)離奇詭異幌缝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)诫欠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門涵卵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呕诉,你說我怎么就攤上這事缘厢〕远龋” “怎么了甩挫?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)椿每。 經(jīng)常有香客問我伊者,道長(zhǎng),這世上最難降的妖魔是什么间护? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任亦渗,我火速辦了婚禮,結(jié)果婚禮上汁尺,老公的妹妹穿的比我還像新娘法精。我一直安慰自己,他們只是感情好痴突,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布搂蜓。 她就那樣靜靜地躺著,像睡著了一般辽装。 火紅的嫁衣襯著肌膚如雪帮碰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天拾积,我揣著相機(jī)與錄音殉挽,去河邊找鬼。 笑死拓巧,一個(gè)胖子當(dāng)著我的面吹牛斯碌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播肛度,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼输拇,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了贤斜?” 一聲冷哼從身側(cè)響起策吠,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤逛裤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后猴抹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體带族,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蟀给,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蝙砌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡跋理,死狀恐怖择克,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情前普,我是刑警寧澤肚邢,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站拭卿,受9級(jí)特大地震影響骡湖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜峻厚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一响蕴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惠桃,春花似錦浦夷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至誓禁,卻和暖如春懈息,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背摹恰。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工辫继, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俗慈。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓姑宽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親闺阱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子炮车,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344