微软面试题: LeetCode 2. 括号生成 middle 出现次数:3

题目描述:c++

  数字 n 表明生成括号的对数,请你设计一个函数,用于可以生成全部可能的而且 有效的 括号组合。函数

方法一: 回溯 + 剪枝 spa

将 生成 n 对 有效括号的过程就是在一棵剪枝了的二叉树上遍历的过程。下图是 n = 3 的状况。设计

 

 

 

  从上面的图片中咱们能够很明显的看到,最后五条画黑线的叶节点就是最终的结果,其中左分支都是添加左括号,code

右分支都是添加右括号。blog

       添加左(右)括号的条件是 当前还有 左(右)括号能够用,特别地,添加右括号还须要当前 已经添加的右括号的数量图片

不能比已经添加的左括号的多。由于 合法的括号序列的第一个必定是左括号,此时右括号数量要是比左括号多,那必定有右括号数学

尚未左括号配对。string

      因此,剪枝条件 就是  if (l > n || r > n || r > l)  { return } 。l ,r  分别表示当前状态下,序列中 左右括号的数量。初始化为 0;io

      如上图,遍历到黑线叶节点,即获得 了一个合法的 括号序列,须要将获得的合法序列 放到结果集中。

代码以下:

class Solution {
public:
    vector<string> generateParenthesis(int n)
	{
		N = n;
		res.clear();
		dfs("",0,0);
		return res;
    }
	void dfs(string str,int l,int r)
	{
		if(l > N || r > N || r > l)
		{
			return;
		}
		if(l == N && r == N)
		{
			res.push_back(str);
			return;
		}
		dfs(str + '(', l + 1, r);
		dfs(str + ')', l, r + 1);
		return;
	}
private:
	vector<string> res;
	int N;
};

方法二:  动态规划

       分析:动态规划的问题可使用相似于数学概括法的思想来分析,假设咱们已经知道了 0,1,2,... ,n-1 对括号的全部的合法括号序列,

如今 求 有 n 对括号的全部的合法序列。对 一个 有 n 对 括号的 合法括号序列,必定是  '('  开头的 。

       合法括号序列的 形式为 "(" + in_str +")" + out_str  ,且  in_str 和 out_str 都是合法的括号序列串或空串。

假设  "(" + in_str +")" + out_str  是一个有n 对 括号的 合法括号序列,假设 in_str 有 n1 对括号,out_str 有n2 对括号。

 n 1 和 n2 之间必须知足:

 0 <= n1 <= n-1 ,  0 <= n2 <= n-1 ,   n1 + n2 = n - 1  

假设 n = 3 ,则有

       n1     n2

       0       2

       1       1

       2       0

因此,求 有n 对 括号的全部的合法括号序列,即求上面 n_str 和 out_str 的全部组合状况。

另   vector<vector<string> > dp(n+1);   dp[i] 表示 有i  对 括号的 全部合法序列,设 0<= j <= i-1 ,则 in_str 是 dp[ j ]中的一个序列,

同时 out_str 是 dp[i-1 -j] 中的一个序列。

c++  代码以下:

    

 1 class Solution {
 2 public:
 3     vector<string> generateParenthesis(int n) {
 4         vector<vector<string> > dp(n+1);
 5         if( n <= 0)     return {};
 6         //base case
 7         dp[0] = {""};
 8         dp[1] = {"()"};
 9         //dp status move
10         for(int i = 2; i <= n;++i)
11         {
12             for(int j = 0;j <= i-1 ; ++j)
13             {
14                 for(string &in_str:dp[j])
15                    for(string &out_str:dp[i-1-j])
16                    {
17                        string str_tmp = "(" + in_str + ")" + out_str;
18                        dp[i].push_back(str_tmp);
19                    }
20             }
21         }
22         return dp[n];
23     }
24 };
相关文章
相关标签/搜索