【LeetCode】22. Generate Parentheses(C++)

地址:https://leetcode.com/problems/generate-parentheses/

题目:

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n n = 3, a solution set is:
Example:
在这里插入图片描述

理解:

想到了检验是否是有效序列的那道题。
另外,数据结构里经常出的几个数字出入栈的所有可能情况也是一样的。对于有 n n 个数的集合,出入栈情况可以用卡特兰数(Catalan number)计算:
1 n + 1 C 2 n n \frac{1}{n+1}C_{2n}^{n}
这道题是要生成所有的有效序列。
一个重要的性质:在当前位置,如果右括号的数目大于左括号的数目,则该序列一定是无效的。
由于是从左到右生成,因此在每一个位置保证当前位置有效,然后继续插入即可。实现有两种,大同小异,一种传递的是剩余的可用括号数,一种是序列里已有的括号数。

实现1:

这种实现left和right是剩余可添加的括号数。

class Solution {
public:
	vector<string> generateParenthesis(int n) {
		vector<string> res;
		generate(n, n, "", res);
		return res;
	}

	void generate(int left, int right, string curr, vector<string>& res) {
		if (left >= 0 && right >= 0) {
			if (left > right)
				return;
			if (left == 0 && right == 0)
				res.push_back(curr);
			else {
				generate(left - 1, right, curr + "(", res);
				generate(left, right - 1, curr + ")", res);
			}
		}
	}
};

实现2(Backtracking)

class Solution {
public:
	vector<string> generateParenthesis(int n) {
		vector<string> res;
		generate(0, 0, n, "", res);
		return res;
	}

	void generate(int left, int right, const int maxLen, string curr, vector<string>& res) {
		if (curr.size() == 2 * maxLen)
			res.push_back(curr);
		else {
			if (left < maxLen)
				generate(left + 1, right, maxLen, curr + "(", res);
			if (right < left)
				generate(left, right + 1, maxLen, curr + ")", res);
		}
	}
};

复杂度分析:
当可以生成有效的序列时,才会产生函数调用。
卡特兰数的上限有人推导出来是 O ( 4 n n ) O\left(\frac{4^n}{\sqrt{n}}\right)

  • 时间复杂度: O ( 4 n n ) O\left(\frac{4^n}{\sqrt{n}}\right) 。每个有效的序列在backtracking过程中有n步。
  • 空间复杂度: O ( 4 n n ) O\left(\frac{4^n}{\sqrt{n}}\right) ,另外有 O ( n ) O(n) 的空间存储序列。

猜你喜欢

转载自blog.csdn.net/Ethan95/article/details/84330615
今日推荐