题目

给你两个整数 n 和 start。你的任务是返回任意 (0,1,2,,...,2n-1) 的排列 p,并且满足:

p[0] = start

p[i] 和 p[i+1] 的二进制表示形式只有一位不同

p[0] 和 p[2n -1] 的二进制表示形式也只有一位不同

思路

暴力回溯:O(n*2n)

f(s,visited,listRes)用s标识二进制的字符串

if(visited.size())==162)则可以直接返回。

加入s到结果和visited中。

找到s的邻居neib,并且neib步骤visited中:递归访问f(neib,visited,listRes)

回退:从visited和listRes中删除元素。

由于要在队尾队头操作,所以用LinkedList。

最后把得到的listRes的字符串转成十进制数字。

 public List<Integer> circularPermutation(int n, int start) {
List<Integer> res=new ArrayList<>();
String biStart=Integer.toBinaryString(start);
StringBuilder stringBuilder=new StringBuilder(n);
int diffLen=n-biStart.length();
for (int i = 0; i < diffLen; i++) {
stringBuilder.append("0");
}
stringBuilder.append(biStart);
LinkedList<StringBuilder> tmpRes=new LinkedList<>();
int totalSize= (int) (Math.pow(2,n));
helper(tmpRes,stringBuilder,new HashSet<String>(),totalSize);
//把字符串转成int
for (StringBuilder stringBuilder1:tmpRes){
res.add(Integer.parseInt(stringBuilder1.toString(),2));
}
return res;
} /**
*
* @param list
* @param stringBuilder
* @param visited
* @param totalSize
* @return 是否能成功
*/
private boolean helper(LinkedList<StringBuilder> list, StringBuilder stringBuilder, HashSet<String> visited, int totalSize) {
String str=stringBuilder.toString();
visited.add(str);
list.addLast(stringBuilder);
if(visited.size()==totalSize){
return true;
} for (int i = 0; i < stringBuilder.length(); i++) {
//如果没有visite过,则
StringBuilder neib=new StringBuilder(stringBuilder);
char ch=stringBuilder.charAt(i);
neib.setCharAt(i,ch=='0'?'1':'0');
if(!visited.contains(neib.toString())){
if(helper(list,neib,visited,totalSize)){
return true;
}
}
}
visited.remove(str);
list.removeLast(); return false;
}

格雷码O(2N)

先生成所有格雷码,再找到开头

在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),

另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。

生成格雷码的方法:

先生成0~4个元素的格雷码:00,01,11,10

那么4~8的格雷码的生成方法是:在所有元素前面加上1

100,101,111,110,为了能和前四个元素接上,可以把后面这些新元素逆置,换句话说,生成元素的时候选择从后向前变量。

重点在于这种头尾相连的方式。

如果用字符串实现前置1,则需要补0,所以用数字实现更好。

 List<Integer> res=new ArrayList<>();
//
int totalSize= (int) (Math.pow(2,n));
int size=2;
res.add(0);
res.add(1);
int added=2;
while(size<totalSize){
int lastSize=res.size();
for(int i=lastSize-1;i>=0;i--){
res.add(added+res.get(i));//需要补0,直接用数字表示更好
}
added<<=1;
size+=lastSize;
}
//
List<Integer> trueRes=res;
System.out.println(trueRes);
int startPoint=trueRes.indexOf(start);
List<Integer> rt=new ArrayList(trueRes.subList(startPoint,totalSize));
rt.addAll(trueRes.subList(0,startPoint));
return rt;
}

LeetCode1238循环码排列的更多相关文章

  1. LeetCode刷题总结-数学篇

    本文总结LeetCode上有数学类的算法题,推荐刷题总数为40道.具体考点分析如下图: 1.基本运算问题 题号:29. 两数相除,难度中等 题号:166. 分数到小数,难度中等 题号:372. 超级次 ...

  2. 学习sql中的排列组合,在园子里搜着看于是。。。

    学习sql中的排列组合,在园子里搜着看,看到篇文章,于是自己(新手)用了最最原始的sql去写出来: --需求----B, C, F, M and S住在一座房子的不同楼层.--B 不住顶层.C 不住底 ...

  3. [LeetCode] Arranging Coins 排列硬币

    You have a total of n coins that you want to form in a staircase shape, where every k-th row must ha ...

  4. [LeetCode] Next Permutation 下一个排列

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  5. js学习篇--数组按升序降序排列

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. SDOI 2016 排列计数

    题目大意:一个数列A,n个元素,其中m个元素不动,其他元素均不在相应位置,问有多少种排列 保证m个元素不动,组合数学直接计算,剩余元素错位排列一下即可 #include<bits/stdc++. ...

  7. 排列组合算法的javascript实现

    命题:从成员数为N的集合S中,选出M个元素,分别求其排列与组合结果集,即 A(N, M)与C(N, M) js解法: function queue(arr, size){ if(size > a ...

  8. 剑指Offer面试题:26.字符串的排列

    一.题目:字符串的排列 题目:输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a.b.c所能排列出来的所有字符串abc.acb.bac.bca.cab和cba. 二 ...

  9. .NET平台开源项目速览(11)KwCombinatorics排列组合使用案例(1)

    今年上半年,我在KwCombinatorics系列文章中,重点介绍了KwCombinatorics组件的使用情况,其实这个组件我5年前就开始用了,非常方便,麻雀虽小五脏俱全.所以一直非常喜欢,才写了几 ...

随机推荐

  1. Linux文件系统属性和权限概念详解(包含inode、block、文件权限、文件软硬链接等)

    Linux中的文件属性 ls -lih 包括:索引节点(inode),文件类型,权限属性,硬链接数,所归属的用户和用户组,文件大小,最近修改时间,文件名等等 索引节点:相当于身份证号,系统唯一,系统读 ...

  2. 百页 PPT BPF 技术全览 - 深入浅出 BPF 技术

    eBPF 从创建开始,短短数年(7年),至今就已经被认为是过去 50 年来操作系统最大的变更,那么 eBPF 技术到底给我们带来了什么样的超能力,以至于得到如此高的评价? 本文从以下内容入手,对 eB ...

  3. SpringCloud微服务实战——搭建企业级开发框架(三十一):自定义MybatisPlus代码生成器实现前后端代码自动生成

      理想的情况下,代码生成可以节省很多重复且没有技术含量的工作量,并且代码生成可以按照统一的代码规范和格式来生成代码,给日常的代码开发提供很大的帮助.但是,代码生成也有其局限性,当牵涉到复杂的业务逻辑 ...

  4. day01 前端bootstrap框架

    day01 django框架之bootstrap框架 今日内容概要 前端框架之bootstrap 该框架支持cv编写前端页面 利用socket模块编写一个简易版本的web框架 利用wsgiref模块编 ...

  5. pymongdb入门

    Pymongo入门 安装 pip install pymongo 连接 实际就是实例化一个客户端对象,然后客户端对象中指定一个库作为库对象,库对象中的集合对象就是之后常用来执行操作的对象 1 ''' ...

  6. 大数据学习day17------第三阶段-----scala05------1.Akka RPC通信案例改造和部署在多台机器上 2. 柯里化方法 3. 隐式转换 4 scala的泛型

    1.Akka RPC通信案例改造和部署在多台机器上  1.1 Akka RPC通信案例的改造(主要是把一些参数不写是) Master package com._51doit.akka.rpc impo ...

  7. 零基础学习java------day11------常用API---Object、Scanner、String、StringBufer/StringBuilder

    API概述 API(application Programming Interface, 应用程序编程接口),是一些预先定义的函数.目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力, ...

  8. MYSQL获取更新行的主键ID 【转】

    在某些情况下我们需要向数据表中更新一条记录的状态,然后再把它取出来,但这时如果你在更新前并没有一个确认惟一记录的主键就没有办法知道哪条记录被更新了. 举例说明下: 有一个发放新手卡的程序,设计数据库时 ...

  9. Oracle异常处理——ORA-01502:索引或这类索引的分区处于不可用状态

    Oracle异常处理--ORA-01502:索引或这类索引的分区处于不可用状态参考自:https://www.cnblogs.com/lijiaman/p/9277149.html 1.原因分析经过查 ...

  10. 【Linux】【Services】【Package】Basic

    Linux程序包管理           概述         API:Application Program Interface         ABI:Application Binary Int ...