给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
分析:本题是在字符串的分类里面,但实际用的是回溯算法。在回忆之前回溯算法题的解法时,发觉回溯跟dfs方式是一样的,不知道他们区别是什么,就在网上搜了一下。
“Backtracking is a more general purpose algorithm.
Depth-First search is a specific form of backtracking related to searching tree structures. From Wikipedia:
One starts at the root (selecting some node as the root in the graph case) and explores as far as possible along each branch before backtracking.
It uses backtracking as part of its means of working with a tree, but is limited to a tree structure.
Backtracking, though, can be used on any type of structure where portions of the domain can be eliminated – whether or not it is a logical tree. The Wiki example uses a chessboard and a specific problem – you can look at a specific move, and eliminate it, then backtrack to the next possible move, eliminate it, etc.”
这是stackOverflow上面的一个回答,大致意思是回溯是一种可以通用的算法,而dfs是回溯算法在树形结构的一种特殊用法。恩。。大概了解了一些。。
之前的回溯题目解法一般是数组座标的回溯运动,这是第一次用到字符串上,它的过程和边界也比较有意思。上网搜了解法,理清了回溯过程,写成swift提交上去,通过。
class Solution {
func generateParenthesis(_ n: Int) -> [String] {
var res = [String].init()
dfs("", &res, n, 0, 0);
return res;
}
func dfs(_ cur:String ,_ res:inout [String], _ n:Int, _ left:Int, _ right:Int) {
if right == n {
res.append(cur)
}
if left < n {
dfs(cur+"(", &res, n, left+1, right);
}
if right < left {
dfs(cur+")", &res, n, left, right+1);
}
}
}
反思:回溯的形式还是很多,条件写起来也不太容易,还需要多练习。