问题

n对括号有多少种合法的组合,写出一个可以执行出该结果的函数:

当n=1时,输出["()"];

当n=2时,输出["(())","()()"];

当n=3时,输出["((()))","(()())","(())()","()(())","()()()"];

思路

问题等价为:在一个字符串中包含两种字符:'('和')',他们出现的次数都为n,并且任何时候'('出现的次数总是大于或等于')'出现的次数。

解决方案:(递归)

标志:l: 左括号出现的次数,r:右括号出现的次数,n: 括号对数,s: 存储符合要求的排列字符串,num: 匹配排列种数,arr:存储结果集;

步骤:

1.如果r=n,即右括号已出现了n次,则num++,打印s,返回;

2.如果r=l,即左右括号出现次数相等(且<n,这由1知),则在s后面append字符‘(’,并l++,回到1(递归);

3.如果r<l,即右括号出现次数小于左括号,分两种情况

(1),l=n,即左括号全部出现,则在s后面append字符')',并r++,回到1(递归);

(2),l<n,则接下来出现的字符可能是'(',也可能是')',可以:

在s后append字符‘(’,l++,回到1(递归);然后把s最后的字符'('pop出来,append字符‘)’,l--,r++,再回到1(递归);

解题思路参考链接:

https://blog.csdn.net/u014529413/article/details/39119273

知道了解题思路,那么现在就可以用语言程序来编写测试输出结果:

1.用php实现:

代码示例(这里我用了php7的写法):

<?php
// 严格模式
declare(strict_types=1); /**
* 输出n对括号组合
* @param int $l [l表示已有左括号个数]
* @param int $r [r表示已有右括号个数]
* @param int $n [n表示括号对数]
* @param string $s [存储符合要求的排列字符串]
* @param int &$num [引用传递:匹配排列种数n]
* @param array &$arr [引用传递:結果集]
* @return array [description]
*/
function nBrackets(int $l,int $r,int $n,string $s,int &$num,array &$arr):array{
if($r == $n){
$num++;
// echo "$s\n";
$arr[] = $s;
return $arr;
}
if($r == $l)
{
$s=$s.'(';
$l++;
nBrackets($l,$r,$n,$s,$num,$arr);
}else{
//$r<$l
if($l == $n){
$s=$s.')';
$r++;
nBrackets($l,$r,$n,$s,$num,$arr);
}else{
$s=$s.'(';
$l++;
nBrackets($l,$r,$n,$s,$num,$arr);
$s = substr($s,0,strlen($s)-1);
$l--;
$s=$s.')';
$r++;
nBrackets($l,$r,$n,$s,$num,$arr);
} }
return $arr;
} $n=4;
$num=0;
$s='';
$arr = array();
$arrRs = nBrackets(0,0,$n,$s,$num,$arr);
echo json_encode($arrRs,JSON_UNESCAPED_UNICODE);
echo "\n共".$num."种";

输出结果:

["(((())))","((()()))","((())())","((()))()","(()(()))","(()()())","(()())()","(())(())","(())()()","()((()))","()(()())","()(())()","()()(())","()()()()"]

共14种

2.用go实现:

代码示例(go的类型声明是放在变量后面,与其他语言有些区别):

package main

import "fmt"

/**
* 输出n对括号组合
* @param l int [l表示已有左括号个数]
* @param r int [r表示已有右括号个数]
* @param n int [n表示括号对数]
* @param s string [存储符合要求的排列字符串]
* @param $num int [引用传递:匹配排列种数n]
* @param $arr array [引用传递:結果集]
* @return array [description]
*/
func nBrackets(l int, r int, n int, s string, num *int, arr *[]string) []string {
if r == n {
*num++
//println(s,"\n")
*arr = append(*arr, s)
return *arr
}
if r == l {
s = fmt.Sprintf("%s%s", s, "(")
l++
nBrackets(l, r, n, s, num, arr)
} else {
//r<l
if l == n {
s = fmt.Sprintf("%s%s", s, ")")
r++
nBrackets(l, r, n, s, num, arr)
} else {
s = fmt.Sprintf("%s%s", s, "(")
l++
nBrackets(l, r, n, s, num, arr)
s = s[:len(s)-1]
l--
s = fmt.Sprintf("%s%s", s, ")")
r++
nBrackets(l, r, n, s, num, arr)
}
}
return *arr
} func main() {
var n int = 4
var num int = 0
var s string = ""
var arr []string
var arrRs []string
arrRs = nBrackets(0, 0, n, s, &num, &arr)
fmt.Println(arrRs)
fmt.Print("共", num, "种")
}

输出结果:

[(((()))) ((()())) ((())()) ((()))() (()(())) (()()()) (()())() (())(()) (())()() ()((())) ()(()()) ()(())() ()()(()) ()()()()]

共14种

这里只是我自己根据解题思路所写的例子,如果大家有更好的方法,共同学习,共同进步。

经典问题--php/go输出n对括号的所有组合的更多相关文章

  1. 经典问题——输出n对括号的所有组合

    问题 n对括号有多少种合法的组合,比如两对括号可以有两种:()()和(()) 思路 问题等价为:在一个字符串中包含两种字符:'('和')',他们出现的次数都为n,并且任何时候'('出现的次数总是大于或 ...

  2. 判断括号字符串是否为合法+求n对括号的所有组合

    n对括号的有效组合数 参考:https://zh.wikipedia.org/wiki/%E5%8D%A1%E5%A1%94%E5%85%B0%E6%95%B0 import java.util.Ar ...

  3. Java50道经典习题-程序2 输出素数

    题目:判断101-200之间有多少个素数,并输出所有素数 分析:判断素数的方法:用一个数分别去除2到(这个数-1)的数,如果能被整除,则表明此数不是素数,反之是素数. public class Pro ...

  4. C++入门经典-例2.11-流输出小数控制

    1:代码如下: // 2.11.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...

  5. 求n对括号的合法组合

    一道经典的面试题,求n对括号有多少种合法的组合. 抽象为2n个位置,每个位置可以有2种取值,总共有2^2n个组合,附加约束条件是要符合括号的语法,用来剪枝. 括号语法的合法性条件: 初始化左括号和右括 ...

  6. N对括号的合法组合

    递归实现,需要注意以下几点: 1. 递归终止条件 2. 递归递推关系式 这里实际上是一个排列问题,只是排列需要满足条件在每一次递归调用时左括号数不能少于右括号数. 还有一点需要特别注意,当推出递归调用 ...

  7. LeetCode Generate Parentheses (DFS)

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

  8. 区间dp模型之括号匹配打印路径 poj(1141)

    题目链接:Brackets Sequence 题目描写叙述:给出一串由'(')'' [ ' ' ] '组成的串,让你输出加入最少括号之后使得括号匹配的串. 分析:是区间dp的经典模型括号匹配.解说:h ...

  9. 程序员面试必备经典CTCI,谷歌面试官经典作品!

    1.1 判断一个字符串中的字符是否唯一 1.2 字符串翻转 1.3 去除字符串中重复字符 1.8 利用已知函数判断字符串是否为另一字符串的子串 2.1 从链表中移除重复结点 2.2 实现一个算法从一个 ...

随机推荐

  1. Day06_28_Instanceof关键字 和 引用类型转换

    Instanceof关键字 和 引用类型转换 Instanceof 关键字 - instanceof 是 Java 的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean ...

  2. mysql索引性能验证,高性能的索引策略

    索引性能验证 1.无索引列的查询 在where条件中查询没有添加索引的列,性能会比较差.我们可以先在sqlyog中打开表t_user的数据,然后复制一个名字出来进行查询. /*无索引列的查询,索引不会 ...

  3. 使用MyQR模块生成二维码

    一.介绍 MyQR 模块是 python 的一个外部库,能够将文本或网址转为二维码,扫了之后就能查看文本或跳转到相应网站. 它是一个外部库,需要导入: pip install -i https://p ...

  4. 深度解析Django REST Framework 批量操作

    我们都知道Django rest framework这个库,默认只支持批量查看,不支持批量更新(局部或整体)和批量删除. 下面我们来讨论这个问题,看看如何实现批量更新和删除操作. DRF基本情况 我们 ...

  5. dot 语法总结

    在使用pprof分析go的项目时,经常会查看各项指标的有向图 原理是使用Graphviz(Graph Visualization Software)解析生成的dot脚本得到最终展示给我们的图信息. d ...

  6. 逆向工程第005篇:跨越CM4验证机制的鸿沟(下)

    一.前言 本文是逆向分析CM4系列的最后一篇,我会将该游戏的序列号验证机制分析完毕,进而编写出注册码生成器. 二.分析第二个验证循环 延续上一篇文章的内容,来到如下代码处: 图1 上述代码并没有特别需 ...

  7. hdu2276 矩阵构造

    题意:      给了n个灯泡的状态,他们绕成一个环,0是灭,1是亮,每一秒灯泡的状态都会改变,规则是如果当前这个灯泡的左边的灯泡当前是状态1,那么下一秒当前的这个灯泡状态就改变0变1,1变0,最后问 ...

  8. CVE-2011-0104:Microsoft Office Excel 栈溢出漏洞修复分析

    0x01 前言 上一篇讲到了 CVE-2011-0104 漏洞的成因和分析的方法,并没有对修复后的程序做分析.之后在一次偶然的情况下,想看一看是怎么修复的,结果却发现了一些问题 环境:修复后的 EXC ...

  9. node-全局对象

    Node.js 全局对象 JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量. 全局对象与全局变量 global ...

  10. node-util

    Node.js 常用工具 util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足. util.inherits util.inherit ...