打印n对括号的全部有效组合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/moses1213/article/details/52137902

这道题最基本的思路是求出n对括号的全排列,然后对每种排列方式判定是否有效。判定方法如下:

bool IsMatch(string& str)
{
	if(str.size() % 2 != 0)
		return false;
	int result = 0;	
	for(string::iterator it = str.begin(); it != str.end(); ++it)
	{
		if(*it == '(')
			++result;
		else if(*it == ')')
			--result;
		else
			return false;
			
		if(result < 0)
			return false;
	}
	return result == 0;
}
但是括号只有左括号和右括号,排列组合时有大量重复的匹配排列,每生成一次排列都要排查是不是重复,效率较低。

另一种思路是构造字符串:假设当前插入一个字符,那么有两种选择,插入左括号或者右括号,什么时候可以安全的插入呢?

(1)左括号:插入左括号总是安全的,只有左括号没有使用完,都可以插入左括号。

(2)右括号:插入右括号的时候需要注意,只有当已插入的右括号个数小于左括号的个数时,才可以插入右括号,否则永远无法匹配。

因此函数需要分别记录余下的左括号和右括号数,插入左括号,下面步骤递归插入。或者,插入一个右括号,然后再递归插入,代码如下:

void AddParen(vector<string>& vec, int leftRem, int rightRem, string& str, int index)
{
	if(leftRem == 0 && rightRem == 0)
		vec.push_back(str);
	else
	{
		if(leftRem > 0)
		{
			str[index] = '(';
			AddParen(vec, leftRem-1, rightRem, str, index+1);
		}
		if(rightRem > leftRem)
		{
			str[index] = ')';
			AddParen(vec, leftRem, rightRem-1, str, index+1);
		}
	}
}
	
void GenerateParens(int count)
{
	if(count < 1)
		return;
			
	vector<string> vec;
	string str(count*2, ' ');
	AddParen(vec, count, count, str, 0);
	for(vector<string>::iterator it = vec.begin(); it != vec.end(); ++it)
		cout << *it << " ";
			
	cout << endl;
}



猜你喜欢

转载自blog.csdn.net/moses1213/article/details/52137902