- 与序列相关的问题,参数栈+链表+循环的形式通常更高效
- 对于复用性强,在递归生成括号往往就没有上述高效
问题
给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合。
例如,给出n=3,解集为:
"((()))", "(()())", "(())()", "()()()", "()(())",
递归分析
- 关键 当前位置左括号不少于右括号
golang
字符串不可变,故可用字节切片生成字符串append
生成的数据依赖于底层数组,有可变性,正常情况下用copy
得到副本- 计数边界,分层递进与回溯,回溯期递进入参反向,函数栈
func generateParenthesis( n int ) []string {
b := []byte("()")
rs := []string{}
var dfs func(int,int,[]byte)
dfs = func(left, right int, path []byte){
if right == n{
rs = append(rs, string(path))
return
}
if left < n{
dfs(left+1,right,append(path,b[0]))
}
if left > right {
dfs(left,right+1,append(path,b[1]))
}
}
dfs(0,0,[]byte{})
return rs
}
栈实现
- 函数栈链表
- 入参,出参,返回调用点
func generateParenthesis(n int) (result []string) {
type resStack struct {
Prev string
Left int
Right int
Next *resStack
}
res := &resStack{
Prev: "",
Left: n,
Right: n,
}
head := res
for head != nil {
if head.Left == 0 && head.Right == 0 {
result = append(result, head.Prev)
head = head.Next
continue
}
if head.Left != 0 {
res.Next = &resStack{
Prev: head.Prev + "(",
Left: head.Left - 1,
Right: head.Right,
}
res = res.Next
}
if head.Right > head.Left {
res.Next = &resStack{
Prev: head.Prev + ")",
Left: head.Left,
Right: head.Right - 1,
}
res = res.Next
}
head = head.Next
}
return
}