給定乙個字串只包含』(『和』)』,輸出其中最長的括號正確匹配的子串行的長度。
輸入輸出
())2
)()())
4(()
2(()()()()(
8以下將介紹三種複雜度為o(n)的演算法
該演算法利用了棧來遍歷可能的匹配的括號子串行,遍歷的同時找出最長的子串行。遍歷不會遍歷所有的匹配括號子串行,併排的一些括號只有包含最左邊括號的子串行被遍歷,最長的括號子串行肯定能被遍歷。
棧頂記錄的是與目前探查的括號序列並列的最左邊的括號的前乙個字元的位置。
從左向右遍歷字串元素。遇到左括號則將該位置壓入棧。如果遇到右括號的話,如果不能與棧頂的左括號匹配,則說明這個右括號是多餘的,壓入棧。如果遇到右括號能匹配,則找到了乙個括號序列。這個時候棧頂元素為與這個右括號匹配的左括號的位置。但注意到可能有多個括號並列的情況,進行一次出棧後棧頂元素就是與目前探查的括號序列並列的最左邊的括號的前乙個字元的位置。觀察到了乙個新的括號序列,更新最大長度。
int
longestvalidparentheses1
(std:
:string s)
else
}return result;
}
演算法2使用了動態規劃思想。使用乙個陣列記錄以i結尾的最大匹配括號子串行長度。
還是從左向右遍歷字串,同時記錄左括號減去右括號的個數,最小為0,藉此可以忽略多餘的右括號。找到了乙個不多餘的右括號後,計算以他結尾的括號序列長度,不僅包括這對括號內部的括號,還要加上這對括號前面的與其並列的括號。
int
longestvalidparentheses2
(std:
:string s)
else
if(leftparenthesescount >0)
result = std:
:max
(result, lenoflongestparenendedat[i]);
}}return result;
}
這個演算法不僅時間複雜度為o(n),而且空間複雜度為o(1)。
原字串中匹配序列左側要麼是空要麼是括號不匹配的,右側也一樣。字串相當於乙個已經匹配的括號序列左邊和右邊加入不匹配的括號序列產生的。
對於乙個括號完全匹配的字串,在從左向右遍歷的同時記錄左括號和右括號的個數,那麼顯然遇到左括號個數等於右括號個數的時候則已經遍歷的部分是括號完全匹配的,匹配括號序列中左括號數目等於右括號數目,這樣就可以知道匹配括號子串行的長度。在這個的基礎上,如果在字串的右邊加入乙個括號不匹配的序列,則原演算法可以繼續工作。如果在字串左側加入乙個右括號比左括號多的序列,則原來的演算法無法工作,但是只要發現右括號比左括號多則將已遍歷的部分去掉,即將計數清零,演算法就可以繼續工作。如果在字串左側加入乙個左括號比右括號多的序列,則原來的演算法無法工作。這個時候只要從右向左再進行一遍上述演算法,就能正常工作。
int
longestvalidparentheses3
(std:
:string s)
else
if(leftnum == rightnum)
else
if(rightnum > leftnum)
} leftnum = rightnum =0;
for(
int i = s.
length()
-1; i >=
0; i--
)else
if(leftnum == rightnum)
else
if(leftnum > rightnum)
}return result;
}
正確匹配的最長的括號子串
分析 使用字串進出棧來模擬括號的匹配,棧中儲存沒有進行匹配的字串,掃瞄字串,對於第i個字元,如果該字元為 則進棧,如果該字元為 並且棧頂字元是 則進行匹配,否則不匹配,字元進棧。對於進行匹配的字元,判斷以該右括號結尾的最大匹配子串 最大匹配子串即為該右括號向前到第乙個未匹配字元之間的子串 比當前已找...
DP 括號匹配序列問題
簡單括號匹配問題是給出字串,判斷字串中的括號是否匹配,此類問題核心解決方案就是利用棧的後進先出的特性,從左到右依次遍歷字串,遇左括號進棧,遇右括號將其與棧頂元素配對,若能配對,則棧頂元素出棧,繼續遍歷,若不能配對,則返回false。字串遍歷結束後,判斷棧是否為空,若不為空返回false,若為空,返回...
HRBUST 2230 括號子串行 A(DP)
一段括號序列被稱為平衡的,如果對於任意字首,左括號的數目都不小於右括號。給定一段括號序列,問有多少括號子串行是平衡的。內容相同但位置不同的算兩種。input 輸入一行括號序列,括號序列的長度 100。output 輸出一行表示答案模 10 9 7 後的結果。sample input sample o...