5. 涉及知識點
[給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。
例如,給出 n = 3,生成結果為:
[「((()))」,
「(()())」,
「(())()」,
「()(())」,
「()()()」
]本題目的是將括號隨機組合,並且滿足括號為有效括號,即"()",思路如下:
(1)建立字典dict = ,將前括號"(「標記為1,後括號」)"標記為-1;
(2)先採用暴力方法遍歷所有排列組合的可能性,比如當n為3時,所有的可能性如下所示:
(1, -1, 1, -1, -1, 1)
(1, -1, -1, -1, 1, 1)
(-1, 1, 1, -1, -1, 1)
(-1, 1, -1, 1, 1, -1)
(-1, 1, -1, -1, 1, 1)
(-1, -1, 1, 1, 1, -1)
(1, -1, 1, -1, 1, -1)
(-1, 1, 1, 1, -1, -1)
(-1, -1, 1, -1, 1, 1)
(1, 1, -1, -1, 1, -1)
(1, -1, -1, 1, -1, 1)
(-1, 1, 1, -1, 1, -1)
(1, 1, 1, -1, -1, -1)
(-1, 1, -1, 1, -1, 1)
(-1, -1, -1, 1, 1, 1)
(-1, -1, 1, 1, -1, 1)
(1, -1, 1, 1, -1, -1)
(1, -1, -1, 1, 1, -1)
(1, 1, -1, 1, -1, -1)
(1, 1, -1, -1, -1, 1)
(3)對每種可能性的前1~n*2項分別求和,需要滿足求的每次和都大於等於0,比如(1, 1, -1, 1, -1, -1),每次求和的值1(1,),2(1+1),1(1+1-1),2(1+1-1+1),1(1+1-1+1-1),0(1+1-1+1-1-1),每次求和都大於等於0,滿足題目的意思。
(4)用字典將1替換成「(」,-1替換成「)」
# 自己解法 (存在問題,當n較大時,執行時間過長)
#(甲)
import itertools
class
solution
:def
generateparenthesis
(n):
""" :type n: int
:rtype: list[str]
"""src =[1
]* n
for i in
range
(int
(n)):-
1)a =
list
(set
(itertools.permutations(src,
len(src)))
) vf =
for i in
range
(int
(len
(a))):
for j in
range
(n*2):
ifsum
(a[i][0
:j+1])
<
0& j+
1< n*2:
break
elif j+
1== n*2:
b = a[i]
rep =
["("
if x ==
1else
")"for x in b]
f ="".join(rep)
return vf
網上最優解法
方法一:暴力法
思路我們可以生成所有 2^個 『(』 和 『)』 字元構成的序列。然後,我們將檢查每乙個是否有效。
演算法為了生成所有序列,我們使用遞迴。長度為 n 的序列就是 『(』 加上所有長度為 n-1 的序列,以及 『)』 加上所有長度為 n-1 的序列。
為了檢查序列是否為有效的,我們會跟蹤平衡,也就是左括號的數量減去右括號的數量的淨值。如果這個值始終小於零或者不以零結束,該序列就是無效的,否則它是有效的。
class
solution
(object):
defgenerateparenthesis
(self, n)
:def
generate
(a =
):iflen
(a)==
2*n:
if valid(a):""
.join(a)
)# 將判斷後有效的list中()連線在一起形成str
else
:'('
)# 構造a的生成過程,在a後面加上"("
generate(a)
# 做一次判斷
a.pop(
)# 刪除a最後乙個元素
')')
# 在a後面加上")"
generate(a)
# 做一次判斷
a.pop(
)# 刪掉a最後乙個元素
defvalid
(a):
# 對於a的有效性判斷,有效括號
bal =
0# 假如前1~2n項中之和有為負,則返回false,
for c in a:
# 否則返回 bal == 0
if c ==
'(': bal +=
1else
: bal -=
1if bal <0:
return
false
return bal ==
0 ans =
generate(
)return ans
方法二:回溯法
思路和演算法
只有在我們知道序列仍然保持有效時才新增 『(』 or 『)』,而不是像方法一那樣每次新增。我們可以通過跟蹤到目前為止放置的左括號和右括號的數目來做到這一點,
如果我們還剩乙個位置,我們可以開始放乙個左括號。 如果它不超過左括號的數量,我們可以放乙個右括號。
class
solution
(object):
defgenerateparenthesis
(self, n)
: ans =
defbacktrack
(s =
'', left =
0, right =0)
:iflen(s)==2
* n:
return
if left < n:
backtrack(s+
'(', left+
1, right)
# 先加"("再加")",保證有效括號
if right < left:
backtrack(s+
')', left, right+1)
backtrack(
)return ans
(1)list(set(itertools.permutations(src,len(src)))),itertools包可以生成數列的所有種可能。
(2)迴圈做break跳出迴圈時,注意break的位置。
LeetCode 其他題目記錄
104.maximum depth of binary tree 和111很像,只是遞迴的結構略有不同,可簡單畫圖分析,求最大深度可以直接返回1 max 左子樹深度,右子樹深度 但是求最小深度時不可以,需要分別考慮左右子樹為空的情況。可以舉個反例子,比如,單斜樹。1 class solution 7...
LeetCode 22 生成括號
22 生成括號 給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。例如,給出 n 3,生成結果為 生成所有 2 個 和 字元構成的序列。然後,我們將檢查每乙個是否有效。為了檢查序列是否為有效的,我們會跟蹤平衡,也就是左括號的數量減去右括號的數量的淨值。如果這個...
LeetCode學習記錄(4) 有效的括號
給定乙個只包括 的字串,判斷字串是否有效。有效字串需滿足 左括號必須用相同型別的右括號閉合。左括號必須以正確的順序閉合。注意空字串可被認為是有效字串。示例 1 輸入 輸出 true示例 2 輸入 輸出 true示例 3 輸入 輸出 false示例 4 輸入 輸出 false示例 5 輸入 輸出 tr...