leetcode之22括号生成Golang

题目描述

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例:

输入:n = 3
输出:[
       "((()))",
       "(()())",
       "(())()",
       "()(())",
       "()()()"
     ]

算法

本题采用回溯算法实现,回溯算法的核心就是采用递归进行深度优先遍历,然后到最底层,就会产生一个结果,如果这个结果是正确的,那么就记录这个结果,如果到了中间某一步,就发现结果是错误的,那么就将产生的中间结果往回退一步,然后走其他路径继续深度遍历。

回溯算法最重要的一步就是每向深处走一步都记录中间结果,当到达某一步发现是错误的时候,就根据前面产生的中间结果往回退一步,进而走其他路径。

本题算法

  • 因为左括号和右括号的数量是一样多的,所以当要形成正确的结果的前提就是已经到达某一步时,已经使用的左括号的数量一定是大于或者等于已经使用的右括号的数量的。
  • 当左括号和右括号的数量都变成了零的时候,当前这个结果就是正确的,记录这个结果,并且根据中间结果往回退一步,继续走其他路径。
  • 当剩下的左括号的数量少于剩余的右括号数量时
    • 如果左括号和右括号的数量都不为0
      • 那么有两种走法,就是使用左括号走下一步和使用右括号走下一步
    • 如果左括号的数量为0,那么就只能用右括号走下一步了

代码

func generateParenthesis(n int) []string {
	// 记住回溯算法的核心就是深度遍历,每次直接遍历到底,然后返回结果
	// 如果是正确的结果,那么就将结果存入结果集合
	// 如果是错误的结果,那么就舍弃这个结果
	res := make([]string, 0)
	if n <= 0 {
		return res
	}
	var create func(left, right int, parentRes []byte)
	create = func(left, right int, parentRes []byte) {
		if left == 0 && right == 0 {
			res = append(res, string(parentRes))
			return
		}
		if left == right {
			parentRes = append(parentRes, '(')
			create(left-1, right, parentRes)
		} else {
			if left < right {
				flag := false
				if left != 0 {
					flag = true
					parentRes = append(parentRes, '(')
					create(left-1, right, parentRes)
				}
				if right != 0 {
					if flag {
						parentRes[len(parentRes)-1] = ')'
					} else {
						parentRes = append(parentRes, ')')
					}
					create(left, right-1, parentRes)
				}
			}
		}
	}
	single := []byte{}
	create(n, n, single)
	return res
}
posted @ 2020-11-12 23:26  胖胖咩  阅读(159)  评论(0)    收藏  举报