【算法】Longest Valid Parentheses 最長(zhǎng)有效括號(hào)

題目

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

Example 1:

Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"

Example 2:

Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"

給出一個(gè)只含有 "("意系、")" 的字符串绘搞,尋找字符串中最長(zhǎng)的有效括號(hào)的長(zhǎng)度。

解題思路

這里就需要分析一下 "()" 的特性了:

  1. "()" 的長(zhǎng)度為 2
  2. ”()“ 左右位置若存在有效括號(hào)爱态,則可以進(jìn)行拼接
  3. "()" 若有效,且其中間位置存在字符教届,則中間的字符串也一定為有效括號(hào)

依據(jù)這三點(diǎn)特性栗涂,可以考慮如下思路來尋找最長(zhǎng)括號(hào):

  1. 從左到右遍歷字符串苇侵,找到有效的括號(hào),并計(jì)算其本身的長(zhǎng)度
    • 以找到 ")" 為 當(dāng)前標(biāo)識(shí) 历恐,再尋找與其匹配的 "("寸癌,若找到則為有效括號(hào)
    • 假設(shè)當(dāng)前有效括號(hào)中間含有有效括號(hào)M,尋找與其匹配的 "("
      • 找到當(dāng)前字符 ")" 的位置為 i 弱贼,每個(gè)有效括號(hào)的當(dāng)前最長(zhǎng)長(zhǎng)度存進(jìn) max[i],
      • 當(dāng)前位置 i 左移到 有效括號(hào)M 的左側(cè)( 左移 max[i-1] + 1 位),即為當(dāng)前有效括號(hào)的 "(" 的位置 j = i - 1 - max[i-1]
      • 當(dāng)且僅當(dāng)位置 j 的字符存在且為 "(" 時(shí)吮旅,當(dāng)前有效括號(hào)的假設(shè)才成功溪烤,當(dāng)前有效括號(hào)的長(zhǎng)度為當(dāng)前左右括號(hào)長(zhǎng)度 2 加上 有效括號(hào)M 的長(zhǎng)度 max[i-1],( 2 + max[i-1])
  2. 由于是從左到右遍歷庇勃,所以若左邊位置為有效括號(hào)(有效括號(hào)L)檬嘀,計(jì)算最長(zhǎng)長(zhǎng)度時(shí),需要加上 有效括號(hào)L 的長(zhǎng)度 max[j-1]
  3. 計(jì)算完 max[i] 與結(jié)果容器 res 做較大值比較责嚷,賦較大值給 res
  4. 遍歷結(jié)束鸳兽,返回 res 即為最長(zhǎng)有效括號(hào)的長(zhǎng)度

PS: 有效括號(hào)M 若存在,其長(zhǎng)度為 max[i-1] 有值再层, 有效括號(hào)M 若不存在 max[i-1] 為 0贸铜,若 當(dāng)前有效括號(hào) 中間位置沒有字符時(shí)堡纬,i-1 位置為 "(",其在max的值max[i-1]也為 0 蒿秦,所以 當(dāng)前有效括號(hào) 中間沒有字符時(shí)的長(zhǎng)度計(jì)算方式和 有效括號(hào)M 不存在時(shí)的計(jì)算方式是一致的烤镐,用 j = i - 1 - max[i-1] 尋找匹配 "(" 的方式可以同時(shí)解決。

代碼實(shí)現(xiàn)

Runtime: 12 ms
Memory: 20.9 MB

func longestValidParentheses(_ s: String) -> Int {
        let len = s.count
        // 長(zhǎng)度小于 2 的時(shí)候棍鳖,成不了一組 () 所以返回 0
        if len < 2 {
            return 0
        }
        // 將 s 轉(zhuǎn)換成數(shù)組炮叶,方便操作
        let s = Array(s)
        // max 數(shù)組 記錄當(dāng)前有效括號(hào)最大長(zhǎng)度
        var max = Array(repeating: 0, count: len)
        // res 作為結(jié)果
        var res = 0
        // 從 1 開始遍歷 s
        for i in 1 ..< len {
            // 只有當(dāng)前字符為 ")" 時(shí)浑彰,才有可能出現(xiàn)有效括號(hào)
            if s[i] == ")" {
                // 用 i 減去 max[i-1] 的中間位置有效括號(hào)長(zhǎng)度镀裤,再減去當(dāng)前字符長(zhǎng)度 1,即為與當(dāng)前有效括號(hào)的 ( 的位置 j
                let j = i - 1 - max[i-1];
                // 只有當(dāng) j >= 0禽绪,并且 s[j] 為 ( 時(shí)医瘫,有效括號(hào)才匹配
                if j >= 0 && s[j] == "(" {
                    //有效括號(hào)匹配侣肄,更新 max[i] 的值,當(dāng)前成對(duì)括號(hào)長(zhǎng)度 2 醇份,中間位置有效括號(hào)長(zhǎng)度 max[i-1]稼锅,左側(cè)有效括號(hào)長(zhǎng)度 max[j-1],加和在一起
                    max[i] = 2 + max[i-1] + (j > 1 ? max[j-1] : 0)
                    //更新較大值到 res
                    res = max[i] > res ? max[i] : res
                }
            }
        }
        return res
    }

代碼地址:https://github.com/sinianshou/EGSwiftLearning

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末僚纷,一起剝皮案震驚了整個(gè)濱河市矩距,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌怖竭,老刑警劉巖锥债,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異痊臭,居然都是意外死亡哮肚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門趣兄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绽左,“玉大人,你說我怎么就攤上這事艇潭∑纯” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵蹋凝,是天一觀的道長(zhǎng)鲁纠。 經(jīng)常有香客問我,道長(zhǎng)鳍寂,這世上最難降的妖魔是什么改含? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮迄汛,結(jié)果婚禮上捍壤,老公的妹妹穿的比我還像新娘骤视。我一直安慰自己,他們只是感情好鹃觉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布专酗。 她就那樣靜靜地躺著,像睡著了一般盗扇。 火紅的嫁衣襯著肌膚如雪祷肯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天疗隶,我揣著相機(jī)與錄音佑笋,去河邊找鬼。 笑死斑鼻,一個(gè)胖子當(dāng)著我的面吹牛蒋纬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坚弱,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼颠锉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了史汗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤拒垃,失蹤者是張志新(化名)和其女友劉穎停撞,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悼瓮,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡戈毒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了横堡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片埋市。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖命贴,靈堂內(nèi)的尸體忽然破棺而出道宅,到底是詐尸還是另有隱情,我是刑警寧澤胸蛛,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布污茵,位于F島的核電站,受9級(jí)特大地震影響葬项,放射性物質(zhì)發(fā)生泄漏泞当。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一民珍、第九天 我趴在偏房一處隱蔽的房頂上張望襟士。 院中可真熱鬧盗飒,春花似錦、人聲如沸陋桂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽章喉。三九已至汗贫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秸脱,已是汗流浹背落包。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摊唇,地道東北人咐蝇。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像巷查,于是被迫代替她去往敵國和親有序。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

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