问题

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. Tomcat9配置HTTP/2

    1 概述 Tomcat从Tomcat8的一些较新版本就支持HTTP/2了,Tomcat9直接支持,本文首先讲述了相关HTTP/2的特性,接着利用一个简单的开源工具mkcert生成证书并利用该证书配置H ...

  2. shell脚本 4 函数与正则

    shell函数 shell中允许将一组命令集合或语句形成一段可用代码,这些代码块称为shell函数.给这段代码起个名字称为函数名,后续可以直接调用该段代码. 格式 func() {   #指定函数名 ...

  3. Go-06-数据类型、常量、运算符

    数据类型转换 Go语言采用数据类型前置加括号的方式进行类型转换,格式如:T(表达式).T表示要转换的类型:表达式包括变量.数值.函数返回值等. var a int =100 b := float(a) ...

  4. 002-Java的标识符和关键字

    目录 一.标识符 1.什么是标识符 2.标识符的命名规则 3.标识符的命名规范 二.关键字 1.什么是关键字 2.Java中的关键字 一.标识符 1.什么是标识符   标识符就是程序员自己规定的代表一 ...

  5. 963. Minimum Area Rectangle II

    Given a set of points in the xy-plane, determine the minimum area of any rectangle formed from these ...

  6. 软件篇-02-基于ZED 2和ORB_SLAM2的SLAM实践

    时隔两周,我又回来了. ​ 本期内容如题,ZED 2的SDK功能还是挺多的,包括轨迹跟踪,实时建图等等.虽然由于是商业产品,我看不到他们的源代码,但是根据使用情况来看,ZED 2内部是采用了IMU和光 ...

  7. hdu4982 暴搜+剪枝(k个数和是n,k-1个数的和是平方数)

    题意:       给你两个数n,k问你是否怎在这样一个序列:      (1)这个序列有k个正整数,且不重复.      (2)这k个数的和是n.      (3)其中有k-1个数的和是一个平方数. ...

  8. Web 服务器安全

    目录 Apache Apache出现过的漏洞 Tomcat Tomcat出现过的漏洞 Nginx

  9. C#-DUP

    void jianting() { int port = 8888; UdpClient udpclient = new UdpClient(port); IPEndPoint ipendpoint ...

  10. IT培训软件测试怎么样,问问“过来人”!

    经常看到有人在网上发帖子问:"XX培训(IT培训机构)怎么样,学过的老哥可以出来讲讲真话吗?"问这种问题的同学,来,站起来!我不得不在这儿说你两句:你要想知道一家IT培训机构到底怎 ...