golang 递归 栈 生成括号

  • 与序列相关的问题,参数栈+链表+循环的形式通常更高效
  • 对于复用性强,在递归生成括号往往就没有上述高效

问题

给出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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值