问题

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. Android+Java Web+MySQL实现登录注册

    1 前言&概述 这篇文章是基于此处文章的更新,更新了一些技术栈,更加贴近实际需要,以及修复了若干的错误. 这是一个前端Android+后端Java/Kotlin通过Servelt进行后台数据库 ...

  2. 浅入Kubernetes(8):外网访问集群

    目录 查询 Service Service 外部服务类型 配置 ServiceType 伸缩数量 阶段总结 在前面几篇文章中,我们学习了 kubeadm .kubectl 的一些命令,也学会了 Dep ...

  3. 善用k8s describe

    使用 kubectl describe 来查看某个东西的详细例如 kubectl describe deployment my-nginx kubectl describe svc my-nginx

  4. 锁定项目的 node 版本

    一些老项目对 node 版本是有要求的,往往使用默认的新版本包安装不上,scripts 也跑不起来. 之前就遇到过运行一个小程序项目时,根据文档来,第一步安装就出错.本着办法总比问题多的理念,来一个解 ...

  5. MVC之实现基于token的认证

    安装Nuget包 项目中添加包:dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer 添加认证配置 Startup类中添加如 ...

  6. Linux下用SUID提权

    关于SUID详细:Linux下的用户.组和权限 SUID可以让调用者以文件拥有者的身份运行该文件,所以我们利用SUID提权的思路就是运行root用户所拥有的SUID的文件,那么我们运行该文件的时候就得 ...

  7. LeetCode---11. 盛最多水的容器(Java)

    11. 盛最多水的容器 题目地址:https://leetcode-cn.com/problems/container-with-most-water/ 给你 n 个非负整数 a1,a2,...,an ...

  8. 容器随Docker启动而启动

    在容器开启状态下 docker container update --restart=always 容器名

  9. 【vue-08】vuex

    vuex的作用 简单理解,就是将多个组件共享的变量统一放到一个地方去管理,比如用户登录时的数据token. 快速上手 安装:npm install vuex 首先,我们在src文件夹下创建一个文件夹: ...

  10. burp-suite(Web安全测试工具)教程

    Burp Suite 是用于攻击web 应用程序的集成平台.它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程.所有的工具都共享一个能处理并显示HTTP 消息,持久性,认证,代 ...