最近各厂秋招密集开启了,在此收集面试题助力大家的 offer。
题目描述:
题号:22
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
解题思路:
思路一:回溯
题目要求生成所有有效的括号组合,给定括号对数 n
。有效的括号组合意味着每一个左括号 (
必须有一个对应的右括号 )
并且必须正确地配对。
为了解决这个问题,我们可以使用回溯算法(Backtracking)。回溯算法是一种试探法,通过探索所有可能的路径来找到解决方案。具体到这个问题,我们可以逐步尝试添加左括号 (
和右括号 )
,并在每一步检查是否满足以下条件:
-
左括号的数量不能超过
n
。 -
右括号的数量不能超过左括号的数量(即已添加的
(
数量必须大于或等于已添加的)
数量)。
时间复杂度:时间复杂度可以认为是 O(4^n)
,因为对于每一对括号,我们都有两种选择(放左括号或放右括号,当然需要满足括号匹配的规则),并且这种选择是独立的,直到我们达到 2n
个元素。
空间复杂度:O(4 ^ N)
C++
// C++
class Solution {
vector<string> res;
vector<char> path;
public:
vector<string> generateParenthesis(int n) {
function<void(vector<char>&, int, int, int)> backTrace = [&](vector<char>& path, int left, int right, int n) -> void
{
if(right == n) {
string pathstr(path.begin(), path.end());
res.push_back(pathstr);
}
if(path.empty() || left < n) {
path.push_back('(');
backTrace(path, left + 1, right, n);
path.pop_back();
}
if(right < left) {
path.push_back(')');
backTrace(path, left, right + 1, n);
path.pop_back();
}
};
backTrace(path, 0, 0, n);
return res;
}
};
go
// go
func generateParenthesis(n int) (ans []string) {
var f func(path string, left, right int) // 剩余左括号的数目,剩余右括号的数目
f = func(path string, left, right int) {
if left == 0 && right == 0 {ans = append(ans, path); return}
if left >= 0 {f(path+"(", left-1, right)}
if right > left {f(path+")", left, right-1)}
}
f("", n, n)
return
}