22. 括号生成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/generate-parentheses
著作权归领扣网络所有。
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:
输入:n = 3
输出:[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
暴力破解法:
class Solution {
private $res = [];
/**
* @param Integer $n
* @return String[]
*/
function generateParenthesis($n) {
$this->generateAll($n*2, '');
return $this->res;
}
function generateAll($pos, $curr) {
if ( $pos == strlen($curr) ) {
if ( $this->isValid($curr) ) {
array_push($this->res, $curr);
}
} else {
$this->generateAll($pos, $curr."(");
$this->generateAll($pos, $curr.")");
}
}
function isValid($str) {
$len = strlen($str);
$balance = 0;
for ( $i = 0; $i < $len && $balance >= 0; $i++ ) { //$balance >= 0 避免了 ))、 )( 这样的括弧存在
if ( $str[$i] == '(' ) {
$balance++;
} else {
$balance--;
}
}
return $balance == 0;
}
}
回朔法:
DFS
class Solution {
/**
* @param Integer $n
* @return String[]
*/
function generateParenthesis($n) {
$res = [];
$this->traceback('', $n, $n, $n, $res);
return $res;
}
function traceback($str, $left, $right, $n, &$res) {
if (strlen($str) == $n*2) {
array_push($res, $str);
}
if ($left > 0) {
$this->traceback($str.'(', $left-1, $right, $n, $res);
}
if ($right > $left) {
$this->traceback($str.')', $left, $right-1, $n, $res);
}
}
}
#define N 1500
void generate( char *str, int left, int right, int n, int index, char ** result, int *returnSize );
char ** generateParenthesis( int n, int* returnSize ) {
char ** result = (char **) calloc(sizeof(char *), N);
char *str = (char*)calloc((2 * n + 1), sizeof(char));
*returnSize = 0;
generate(str, n, n, n, 0, result, returnSize);
return result;
}
void generate( char *str, int left, int right, int n, int index, char ** result, int *returnSize ) {
if ( left == 0 && right == 0 ) {
result[(*returnSize)] = (char*)calloc((2 * n + 1), sizeof(char));
strcpy(result[(*returnSize)++], str);
return;
}
if ( left > 0 ) {
str[index] = '(';
generate(str, left-1, right, n, index+1, result, returnSize);
}
if ( right > left ) {
str[index] = ')';
generate(str, left, right-1, n, index+1, result, returnSize);
}
}
BFS
class QueueNode {
public $str = null;
public $left = 0;
public $right = 0;
function __construct($str, $left, $right) {
$this->str = $str;
$this->left = $left;
$this->right = $right;
}
}
class Solution {
private $queue = [];
/**
* @param Integer $n
* @return String[]
*/
function generateParenthesis($n) {
$res = [];
array_unshift( $this->queue, new QueueNode('', $n, $n) );
while ($this->queue) {
$first = array_pop($this->queue);
if ($first->left == 0 && $first->right == 0 ) {
$res[] = $first->str;
}
if ($first->left > 0 ) {
array_push( $this->queue, new QueueNode($first->str.'(', $first->left-1, $first->right) );
}
if ( $first->right > $first->left ) {
array_push( $this->queue, new QueueNode($first->str.')', $first->left, $first->right-1) );
}
}
return $res;
}
}
动态规划
推演过程:
k = i - m - 1
i | m | res[m] | k | res[k] | “(” + res[m]子项 + “)” res[k]子项 | res |
---|---|---|---|---|---|---|
0 | ‘’ | |||||
1 | 0 | res[0] | 0 | res[0] | () | () |
2 | 0 | res[0] | 1 | res[1] | ( ‘’ ) + () | ()() |
2 | 1 | res[1] | 0 | res[0] | (()) + ‘’ | ()() 、(()) |
3 | 0 | res[0] | 2 | res[2] | ( ‘’ ) + ()()、( ‘’ ) + (())、 | ()()() 、()(()) |
3 | 1 | res[1] | 1 | res[1] | ( () ) + () | ()()() 、()(())、((())() |
3 | 2 | res[2] | 0 | res[0] | ( + ()() + )、( + (()) + ) | ()()() 、()(())、(())()、(()())、((())) |
如下为代码:
class Solution {
/**
* @param Integer $n
* @return String[]
*/
function generateParenthesis($n) {
$res[0] = [''];
for ($i = 1; $i <= $n;$i++) {
$curr = [];
for ($m = 0; $m < $i; $m++) {
$k = $i - $m - 1;
foreach ($res[$m] as $mval) {
foreach ($res[$k] as $kval) {
$curr[] = "({$mval}){$kval}";
}
}
}
$res[$i] = $curr;
}
return $res[$n];
}
}
参考大神资料:
https://leetcode-cn.com/problems/generate-parentheses/solution/zui-jian-dan-yi-dong-de-dong-tai-gui-hua-bu-lun-da/
https://leetcode-cn.com/problems/generate-parentheses/solution/di-gui-he-dong-tai-gui-hua-liang-chong-fang-shi-tu/