写完一道题需要更多的思考有没有更优的解决方法。回头看我2022年写的代码,则满是优化点。优秀的程序员不能只是实现功能需求,要对自己的代码有所要求。
1. 题目
n表示生产括号的对数
2. 思想
2.1 方法1
使用深搜。每次有两种选择,入栈,出栈。然后判断得到的字符串结果是否合理即可。
2.2 方法2
仍然是使用深搜,不过针对方法1有改进。方法1中在生成括号后,还有一个后续操作,用于判断生成的字符串是否合法。这么做没问题,但不够高效。更优的做法是:在生成字符串时,就去判断当前是否可以放左括号,还是只能放左括号?是只能放右括号?还是可以放右括号?
3. 代码
3.1 代码1
import copy
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
res = []
self.dfs(n,n,res,[])
return res
# 判断栈括号是否匹配
def judge(self,string):
left = 0
right = 0
for s in string:
if s == "(":
left += 1
else:
if left >0: # 说明有存货
left -=1
else:
return False
return True
# left 表示左括号个数,right表示右括号个数
def dfs(self,left,right,res,tmp):
if left == 0 and right ==0: # 全部放完了
if self.judge(tmp):
res.append(copy.deepcopy("".join(tmp)))
return
# 每次都有两种选择,放left还是放right?
if left:
tmp.append("(")
self.dfs(left-1,right,res,tmp)
tmp.pop()
if right:
tmp.append(")")
self.dfs(left,right-1,res,tmp)
tmp.pop()
3.2 代码2
在放左右括号的时候就判断当前可以放什么括号,那么最后得到的结果就都是合法的了。
class Solution:
res = []
def generateParenthesis(self, n: int) -> List[str]:
self.res.clear()
left_r = right_r = n
left_ready = 0
tmp = []
self.dfs(left_r, right_r, left_ready, tmp)
return self.res
# 深搜找方案个数
# tmp 表示当前的字符串
# left_r 表示 ( 还可以放的个数
# right_r 表示 ) 还可以放的个数
def dfs(self, left_r, right_r, left_ready, tmp):
if left_r == 0 and right_r == 0:
self.res.append("".join(tmp[:]))
return
if left_r:
tmp.append("(")
self.dfs(left_r-1, right_r, left_ready+1,tmp)
del tmp[-1]
if right_r and left_ready:
tmp.append(")")
self.dfs(left_r,right_r-1,left_ready-1,tmp)
del tmp[-1]