经典问题--php/go输出n对括号的所有组合
问题
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对括号的所有组合的更多相关文章
- 经典问题——输出n对括号的所有组合
问题 n对括号有多少种合法的组合,比如两对括号可以有两种:()()和(()) 思路 问题等价为:在一个字符串中包含两种字符:'('和')',他们出现的次数都为n,并且任何时候'('出现的次数总是大于或 ...
- 判断括号字符串是否为合法+求n对括号的所有组合
n对括号的有效组合数 参考:https://zh.wikipedia.org/wiki/%E5%8D%A1%E5%A1%94%E5%85%B0%E6%95%B0 import java.util.Ar ...
- Java50道经典习题-程序2 输出素数
题目:判断101-200之间有多少个素数,并输出所有素数 分析:判断素数的方法:用一个数分别去除2到(这个数-1)的数,如果能被整除,则表明此数不是素数,反之是素数. public class Pro ...
- C++入门经典-例2.11-流输出小数控制
1:代码如下: // 2.11.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...
- 求n对括号的合法组合
一道经典的面试题,求n对括号有多少种合法的组合. 抽象为2n个位置,每个位置可以有2种取值,总共有2^2n个组合,附加约束条件是要符合括号的语法,用来剪枝. 括号语法的合法性条件: 初始化左括号和右括 ...
- N对括号的合法组合
递归实现,需要注意以下几点: 1. 递归终止条件 2. 递归递推关系式 这里实际上是一个排列问题,只是排列需要满足条件在每一次递归调用时左括号数不能少于右括号数. 还有一点需要特别注意,当推出递归调用 ...
- LeetCode Generate Parentheses (DFS)
题意 Given n pairs of parentheses, write a function to generate all combinations of well-formed parent ...
- 区间dp模型之括号匹配打印路径 poj(1141)
题目链接:Brackets Sequence 题目描写叙述:给出一串由'(')'' [ ' ' ] '组成的串,让你输出加入最少括号之后使得括号匹配的串. 分析:是区间dp的经典模型括号匹配.解说:h ...
- 程序员面试必备经典CTCI,谷歌面试官经典作品!
1.1 判断一个字符串中的字符是否唯一 1.2 字符串翻转 1.3 去除字符串中重复字符 1.8 利用已知函数判断字符串是否为另一字符串的子串 2.1 从链表中移除重复结点 2.2 实现一个算法从一个 ...
随机推荐
- Spring Boot demo系列(二):简单三层架构Web应用
2021.2.24 更新 1 概述 这是Spring Boot的第二个Demo,一个只有三层架构的极简Web应用,持久层使用的是MyBatis. 2 架构 一个最简单的Spring Boot Web应 ...
- Java获取多线程执行结果方式的归纳与总结
在日常的项目开发中,我们会经常遇到通过多线程执行程序并需要返回执行结果的场景,下面我们就对获取多线程返回结果的几种方式进行一下归纳,并进行简要的分析与总结. 一.Thread.join 在一些简单的应 ...
- 三. 初步认识Eureka注册中心
Eureka Eureka是Netflix公司出品,英文直译:发现了,找到了! 认识Eureka (一)首先我们来解决第一问题,服务的管理. Ⅰ.早期开发模式中出现的问题 再早期开发时业务时,首先模块 ...
- 【DB宝50】Oracle异构平台迁移之完全可传输导出导入(Full Transportable Export & Import)
目录 一.简介 1.1.使用场景 1.2.限制条件 二.完全可传输操作步骤 三.案例演示 3.1.环境 3.2.源库操作 3.2.1.将需要传输的用户表空间设置为RO状态 3.2.2.使用Data P ...
- HIT手 | 机械电气构造简述和微分运动学及静力学的简单推导
机械结构电气构造简述 HIT手有四个手指,每个手指4个关节,其中第一和第二个关节正交,第三和第四个关节机械耦合,故只有3个自由度,另外大拇指多了一个相对手掌运动的自由度,故一只手掌总共有13各个自 ...
- Android平台下Dalvik层hook框架ddi的研究
通过adbi,可以对native层的所有代码进行hook.但对于Android系统来说,这还远远不够,因为很多应用都还是在Dalvik虚拟机中运行的. 那么,有没有什么办法可以对Dalvik虚拟机中跑 ...
- Linux中的DHCP服务
目录 DHCP DHCP的报文类型 DHCP的部署 DHCP中继(DHCP代理) DHCP DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局 ...
- Windows核心编程 第十七章 -内存映射文件(上)
第1 7章 内存映射文件 对文件进行操作几乎是所有应用程序都必须进行的,并且这常常是人们争论的一个问题.应用程序究竟是应该打开文件,读取文件并关闭文件,还是打开文件,然后使用一种缓冲算法,从文件的各个 ...
- PhpStorm个性化设置推荐
预览 字体 字体使用jetbrains的mono,前往下载:如何安装,字体安装完成之后Restart,可在PhpStorm settings中搜索 font 进行启用 mono 字体 主题 主题推荐使 ...
- 正则表达式:(mysql)REGEXP
检索列prod_name包含文本1000的所以行 SELECT prod_name FROM products WHERE prod_name REGEXP '1000' ORDER BY prod ...