题目很简单,给定数字n,写出所有n组括号的分布情况

例如n=2,则有(()),()(),这两种

n=3,则有

((())),(()()),(())(),()(()),()()() 五种。

看到这个问题,第一反应可能是用递归,要得到 f(n), 等价于再f(n-1)的基础上加一对括号,

只要保证左右括号的相对位置即可!

例如:F(2), 等于再"()"上加一对括号;可能有以下几种情况:

(()),(()),()(),()(),(()),

其中红色是原来的位置,黑色是插入的位置。

显然会出现大量重复组合,所以用这种办法,可能需要借助HashSet来去重。

那有没有更简单的办法呢?


我们将左括号记为 1,右括号记为0,那么n对括号就等价于  n个“1”和n个“0”的组合,构成一个二进制数,且第一位一定是1(左括号),最后一位一定是0(右括号)

所以表现形式位 1xxxxxxxxx0,且每一位的左边1的个数不小于0的个数,每一位的右边,0的个数不小于1的个数。

所以我们有如下算法:

 public static void p8_9(List<int> nums,int left,int right,int remain,int index,int pre){if (remain == 0){nums.Add(pre);return;}if(left>right){//补零不变p8_9(nums, left, right + 1, remain, index - 1, pre);}//补1总是没问题,补1则remain减少pre = pre | (1 << index);index--;left++;remain--;p8_9(nums, left, right, remain, index, pre);}public static void TestP8_9(int n){int num = 1 << (n * 2-1);List<int> nums = new List<int>();p8_9(nums, 1, 0, n - 1, 2 * n - 2, num);nums.ForEach(x => Console.WriteLine(Convert.ToString(x, 2)));}

思路如下:

首先参数:

1 nums:存放最终的排列结果

2.left:统计当前index左边1的个数

3.right:统计当前index左边0的个数

4.index:游标,从左边第二位开始

5.pre:临时存放的数字, 初始为 1<<(2n-1);

6.remain: 剩余需要将0变为1的次数

假设n=3; 构建一个1<<(2*3-1) =100000;

此时参数为 left=1,right=0,remian=2,index=5,pre=100000

a.如果 ramain==0;即已经有三个1了,那么构造结束,将结果加入nums

b.如果左边1的个数大于0的个数比如 110000,那么index=3时,可以设为0,不出出现right>left的情况 ;如果时100000,那么就不能出现100xxx这种结构了,因为后面无论怎么排列都无法使之合法。所以设为0后,right的数目加1,remain保持不变,index往后移(index--).然后继续迭代

c.无论什么情况,只要剩余变1的次数不为0,就可以一直将该位设为1,极端情况就是111000,

这种情况要记得更新remain,他是终止运行的条件。

下面时n=4的运行结果:

10101010
10101100
10110010
10110100
10111000
11001010
11001100
11010010
11010100
11011000
11100010
11100100
11101000
11110000

将1->( ,0->),即可得到最终结果。

当然有个问题是,如果n太大超过16怎么办(即超过int32位数),这里可以用字符串实现,完全没问题。其次参数时可以简化的,知道index和left,right可以计算出来,remain也可以计算出来,这里为了直观,就没有简化。

n对括号的所有的合法组合排序解法相关推荐

  1. 编写一个能够排序的函数模板。_LeetCode刷题——9.给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合...

    难度(medium) 题目描述: 给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合.例如n=3,解集为:  "((()))", "(()())" ...

  2. python文件合法模式组合_以下选项中,不是Python文件二进制打开模式的合法组合是...

    以下选项中,不是Python文件二进制打开模式的合法组合是 答:\"x+\" 建立良好的谈判气氛主要是在( )阶段 答:开局 the ruling class had long b ...

  3. 组合排序题目汇总(排列组合、卡特兰数和递归思想)

    组合排序题目汇总 排列组合 矩阵走法 A必须在B左边站队 互不相邻站队 分糖果 球放入桶 吃糖 卡特兰数 括号匹配 进出栈顺序/售票顺序 二叉树不同的结构数 高矮排列 递归思想 信封装信 排列组合 矩 ...

  4. Numpy 数组复合排序——mX4列,根据多列组合排序

    Numpy 数组复合排序--mX4列,根据多列组合排序 一. Numpy 仅根据某列对 array(mX4)整体排序用argsort import numpy as npdata = np.array ...

  5. 5.12 按照多个条件进行组合排序 [原创Excel教程]

    原文:http://coolketang.com/staticOffice/5a97f32a9f5454403c524f4b.html 1. 本节课将为您演示,如何对表格进行多条件组合排序.首先点击[ ...

  6. 力扣的组合总和解法 (Python)

    力扣的组合总和解法 题目描述: 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidat ...

  7. java util包排序_实现java.util.Comparator接口,对对象集合进行多属性组合排序

    Commons - BeanUtils 提供了很多功能,其中一个很有用的是对对象集合进行排序,如Collections.sort(peoples, new BeanComparator("a ...

  8. sql多维度组合排序

    在写sql的过程中会遇到一种情况,就是多维度组合排序. 比如任务的排序有2个维度,维度1:紧急.不紧急:维度2:领取.未领取,要求按照的如下规则排序: 紧急未领取>紧急领取>不紧急未领取& ...

  9. List多条件组合排序

    直接上代码List组合排序 import java.text.Collator; import java.util.ArrayList; import java.util.Collections; i ...

最新文章

  1. 微信小程序 - 时间戳转时间
  2. 最短路[Dijkstra和堆优化的Dijkstra][Bellman-Ford和SPFA][Floyd最短路](更新中)
  3. asp.net的dropDownlist只显示第一个字
  4. java和ffmpeg使用内存转码_FFMPEG基于内存的转码实例
  5. hashmap赋值给另一个hashmap_图解设计一个 HashMap
  6. java 很多if_java 使用策略模式解决代码中包含太多的if else
  7. 什么是GDT,LDT,GDTR及LDTR?
  8. python3.5安装pygame_安装pygame for Python3.5
  9. Java EE拦截器
  10. 怎样才能在前端职场中拥有更强的竞争力?
  11. 研究人员发现绝大部分酷派(Coolpad)手机暗藏后门(转)
  12. PRML中文版(马春鹏)勘误表
  13. linux tomcat重启 报错,Linux启动Tomcat或停止Tomcat的错误解决方案
  14. Django之kindeditor
  15. 酒店管理系统java实现
  16. Android调用长截屏,Android实现长截屏功能
  17. select默认选中及赋值问题
  18. ipad wifi信号测试软件,iPad3的wifi信号弱 二种方法修复WiFi信号
  19. 基于51单片机步进电机控制
  20. 洛谷P5713 【深基3.例5】洛谷团队系统经典解法

热门文章

  1. 309专供 之 桑葚图
  2. java 三种工厂模式
  3. 2021消防设施操作员(中级)岗位考试模拟题库保养系统知识部分
  4. Bootstrap自适应
  5. 和尤雨溪一起进阶vue
  6. 使用Python玩赤色要塞 初初初级版
  7. java类与对象之实验三
  8. pytorch车牌识别代码
  9. 如何下载并生成等高线
  10. .NetFramework类库迁移到.NetCore过程记录