题解 | #括号生成#

括号生成

http://www.nowcoder.com/practice/c9addb265cdf4cdd92c092c655d164ca

这是一道典型的回溯算法问题,可以将此问题转化为:现在共有2n个位置,每个位置放字符(或者),组成所有的括号组合。

根据回溯框架我们迅速写出一套伪代码:

void backtrack(int n, int i, string&track, vector<string>&res){
	if(i==2*n){
    	res.push_back(track);
     	return;
    }
  	
  for x in ['(', ')']:
  	track.push(x);
  	backtrack(n, i++, track, res);
  	track.pop();
}

然后,根据括号的合法情况,进行剪枝操作。去掉当前右括号比左括号多的情况。因此,分别使用left,right分别技术剩余的左右括号数量。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return string字符串vector
     */
    void backtrack(int left, int right, string& tmp, vector<string>& res){
        if(left<0 || right<0) return;
        if(left>right) return; //左括号剩下的多,说明tmp中右括号多,不合法
        if(left == 0 && right==0){
            res.push_back(tmp);
            return;
        }
        
        tmp.push_back('(');
        backtrack(left-1, right, tmp, res);
        tmp.pop_back();
        
        tmp.push_back(')');
        backtrack(left, right-1, tmp, res);
        tmp.pop_back();
        
    }
    
    vector<string> generateParenthesis(int n) {
        // write code here
        string tmp;
        vector<string> res;
        backtrack(n,n, tmp, res);
        return res;
    }
};

时间复杂度为 递归次数*递归函数本身。

递归次数主要看"状态"的个数,backtrack函数可以看出,left,right, track这三个变量的所有组合个数就是该函数状态的个数。 left和right的组合很容易了解,一共有n的平放种,track的取值范围虽然是0-2n,但是每个胀肚有指数级的括号组合,不好计算。

因此,backtrack函数对应算法的时间复杂度为指数(卡特兰数),空间复杂度为o(1)。

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务