以下三个题都是LeetCode题库里面的。

1.给定一个没有重复数字的序列,返回其所有可能的全排列。
示列:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

整个的过程就如下图,我们可以利用循环让他从第一个元素开始排列,从根开始遍历依次记录节点的值记录在集合之中。

可以根据图可得这是一个回溯算法
1.先去找第一个节点保存他里面的值。
2.再次调用函数 找到去找子集合中不存在的元素并保存(也就是说已经存在的就排除)
3.依次类推,if(size() == num.length)就说明找到第一个排列并保存在集合当中。
4.函数进行回退,删除子集合中的节点。依次类推所有的节点都可求出。

public List<List<Integer>> permute(int[] nums) {List<List<Integer>> list = new ArrayList<>();List<Integer> arrayList = new ArrayList<>();recursion(list,arrayList,nums);return list;}private void recursion(List<List<Integer>> list, List<Integer> arrayList, int[] nums) {if (nums.length == arrayList.size()){//返回的条件是说明第n个排列已找到list.add(new ArrayList<Integer>(arrayList));//将排列添加集合之中return ;}else{for (int i = 0;i < nums.length;i++){if (!arrayList.contains(nums[i])){//如果子集合包括num[i],进行下一次的搜索arrayList.add(nums[i]);//向子集合之中添加搜索到的元素recursion(list,arrayList,nums);arrayList.remove(arrayList.size() - 1);//删除集合中的元素}}}}

以上是我对全排列的理解,可能表述的过程有点问题。但是想法肯定是对的。

2.给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]

这个题和第一题的思路总体一样的,只不过这次有重复的元素,所以我们可以使用set集合来保存元素防止重复的元素出现(使用set集合是为了防止排列的重复,set集合的特性:不允许有重复的元素出现)。

eg:1 1 2 这个序列如果用List集合会出现两次的

这里我们需要注意的是重复元素的出现,所谓的重复元素就两个1不能判断那个使用了,那个没使用所以这里必须添加一个等同大小的数组最好是boolen类型的,用于判断重复元素的使用情况。

public List<List<Integer>> permuteUnique(int[] nums) {Set<List<Integer>> set = new HashSet<>();List<Integer> list = new ArrayList<>();boolean[] tag = new boolean[nums.length];//状态数组Arrays.sort(nums);//对数组进行排序方便处理无序序列recursion(set,list,nums,tag);List<List<Integer>> lists = new ArrayList(set);//将set集合转换为list集合return lists;}private void recursion(Set<List<Integer>> set, List<Integer> list, int[] nums,boolean[] tag) {if (nums.length == list.size()){set.add(new ArrayList<>(list));return;}else{for (int i = 0; i < nums.length; i++) {if (!tag[i]){//tag初始每个元素都是false,false表示当前元素未进入子集合(注意子集合)list.add(nums[i]);tag[i] = true;//元素添加进去后recursion(set,list,nums,tag);tag[i] = false;list.remove(list.size() - 1 );}}}}

什么叫康拓展开?

下式的展开叫做康拓展开:
X=an*(n-1)!+an-1*(n-2)!+…+ai*(i-1)!+…+a21!+a10!
ai为整数,并且0<=ai<i(1<=i<=n),其中ai为小于上一个数字的个数。

康拓展开应用在实际的问题之中就是求解第k个排列。
例如:{1,2,3,4} 这个集合之中 2 3 1 4 这个排列表示的是第几个排列组合。

  1. 2 有1个比他小的所以 1*3!

  2. 3有2个比他小的,但是2已经出现 1*2!

  3. 1没有比他小的所以 0*1!

  4. 4有三个比他小的,但是三个都已出现 ,所以0*0!
    对上述进行求和可得sum = 8;
    所以他是第9个排列。

    LeetCode里面有一道题就是使用康拓展开来做的
    给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
    按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
    "123"
    "132"
    "213"
    "231"
    "312"
    "321"
    给定 n 和 k,返回第 k 个排列。
    说明:
    给定 n 的范围是 [1, 9]。
    给定 k 的范围是[1,  n!]。
    

这道题就是康拓展开的逆过程,当时看见这道题时挺懵的,因为我第一次写的和上面全排列一样在返回集合里去找第k个排列,代码没有任何问题,就是超时了我也很无奈。

这个方法是我利用上面的思想然后获取到集合转换为数组超时了
public String getPermutation(int n, int k) {String str = ("1,2,3,4,5,6,7,8,9").substring(0,n);List<List<Character>> lists = new ArrayList<>();List<Character> list = new ArrayList<>();getBake(lists,list,str);String s = new String();List<Character> characters = lists.get(k - 1);//获取指定的第k个集合Iterator<Character> iterator = characters.iterator();while (iterator.hasNext()){//通过遍历集合存储在字符串中Character next = iterator.next();s += next;}return s;}private void getBake(List<List<Character>> lists, List<Character> list, String str) {if (list.size() == str.length()){lists.add(new ArrayList<>(list));return;}else{for (int i = 0; i < str.length(); i++) {if (!list.contains(str.charAt(i))){list.add(str.charAt(i));getBake(lists,list,str);list.remove(list.size() - 1);}}}}

康拓排列的逆过程

逆过程就是已知这个数是第k个数,求这个数是多少,当然是知道n的值的。

第k个数就是有k-1个数比这个数小。

所以就是 k-1=an*(n-1)!+an-1*(n-2)!+…+a1*0!;

再举一个例子:

如何找出第16个(按字典序的){1,2,3,4,5}的全排列?

首先用16-1得到15

用15去除4! 得到0余15

用15去除3! 得到2余3

用3去除2! 得到1余1

用1去除1! 得到1余0

有0个数比它小的数是1,所以第一位是1

有2个数比它小的数是3,但1已经在之前出现过了所以是4

有1个数比它小的数是2,但1已经在之前出现过了所以是3

有1个数比它小的数是2,但1,3,4都出现过了所以是5

最后一个数只能是2

所以排列为1 4 3 5 2

不知道大家能否看的懂这个逆过程,反正我第一次看逆过程的解析,处于完全懵圈状态,真的是混混然,飘飘然,不知其所以然。

其实就是用它的除后的结果去判断当前位置出现的是什么数字。
public String getPermutation(int n, int k) {int[] number = new int[]{0,1,2,3,4,5,6,7,8,9};List<Integer> list = Arrays.stream(number).boxed().collect(Collectors.toList());int[] fac = new int[]{1,1, 2, 6, 24, 120, 720, 5040, 40320, 362880};//存储1~9的阶乘数k = k - 1;String str = new String();while(n > 0){int value = k / fac[n - 1];//根据公式 除(n-1)!str += list.get(value + 1);//获取value+1是因为list集合之中的第一个元素是0,不是所需排列里面的元素list.remove(value + 1);//获取完直接删除该元素k = k % fac[n - 1];//余数n--;}return str;}

第一次很认真的写文章,可能写的不是很好,但是我会继续改进,坚持写。希望您能点个赞。 如果写的有问题欢迎补充

康拓排列以及全排列老年人听不懂系列相关推荐

  1. 康拓排列的自我总结--以及全排列的递归非递归算法

    写了几个关于全排列的东西,然后就接触到了康拓排列.之前对于全排列的非递归算法耿耿于怀,一只不能找到好的方式.现在好了,有了康拓,什么都解决了. 递归求全排列 我们先来看一个简单的例子,就是如何递归的求 ...

  2. 智能客服“听不懂人话”?消费者很“闹心”

    智能客服与人工客服并非互相取代的关系.人工客服不能缺位,应通过人机协同更好地回应消费者诉求.在金融消费领域,建议与资金安全等密切相关的业务能够设置人工服务"一键转接"或者" ...

  3. 刘烨:家里官方语言是中文 听不懂娘仨说法语

    因参加东方卫视明星旅行真人秀<花样爷爷>,刘烨再一次成为公众的焦点,前天,刘烨在上海接受本报专访,坦言这次参加节目有点被玩了,本想就是演演戏,你好我好大家好,没想到这么苦,这么难.他称现在 ...

  4. 在国外千万不要以为别人都听不懂中文

    在国外千万不要以为别人都听不懂中文  1.有两个女生到法国留学,刚到巴黎,在街上看到一个黑人从对面走来,一个对另一个说 "真黑啊."那个黑人马上走到她们面前说了一句,"就 ...

  5. 别傻啦,不会高数,你连人话都听不懂

    你还在用买菜来搪塞高数 别傻啦,不懂高数你连人话都听不懂 先别急着反驳我,我们先看几个例子: 这是这10年来房价调控时的政府态度: 1,保持房价基本稳定 2.新建住房价格涨幅不高于GDP/人均收入增长 ...

  6. 多语言ASR?没有什么听不懂,15种语言我全都要

    摘要:在这篇博文中,我们介绍来自Google的一篇论文<Scaling End-to-End Models for Large-Scale Multilingual ASR>,来看看如何构 ...

  7. java上课听不懂怎么办_上课听不懂怎么办?我们告诉你解决办法!

    作者:英国教育官方微博 即将开始英国留学生活的同学们,随着开学日期的逐渐临近,你们是不是心中也曾暗暗地唱起过:"离上课越近,我心荡漾-" 尽管通过了"烤鸭"的听 ...

  8. 大学c语言程序设计听不懂,C语言听不懂?那你还不点进来看看?

    最近16级的小鲜肉们结束了为期两周的军训生活,正式开始了自己的的大学学习生活,不过刚一开始上课小鲜肉们就懵了,专业课好难啊!C语言听不懂啊!( Ĭ ^ Ĭ ) 别慌,学长教你几招帮你渡过难关. 小鲜肉 ...

  9. 【英语】为什么老外说的我们听不懂?

    学习音标可以帮助我们念出英文单词的正确发音,不知道大家有没有这样的感受,当你听音频的时候,往往都听不懂,而当让我们看音频的内容,往往能够理解大部分意思,这就是读写英语的能力比听说要强.而我们学习英语不 ...

最新文章

  1. Handlebars模板库浅析
  2. C++ explicit 的用法,就是必须显示调用
  3. 第十三章:位图(五)
  4. 【代码笔记】Web-CSS-CSS 链接(link)
  5. IO虚拟化——Intel VT-d原理
  6. matlab 由图片生成视频
  7. Struts2中数据封装方式
  8. 开发环境很重要,需要学习如何自己搭建开发环境
  9. Windows x64平台 获取PEB表,并获取kernel32.dll的基址,并获取它的函数
  10. pdf文档有时打开乱码的解决方案
  11. 前端安全 XSS跨站脚本攻击-CSRF跨站请求伪造攻击
  12. 局域网常见攻击方式原理
  13. 武汉科技大学计算机学院研究生复试,2019年武汉科技大学硕士研究生复试及录取工作方案...
  14. 解决MATLAB新版本中modem.qammod作废的问题
  15. Qt Android 调用系统文件管理
  16. [UOJ409]Highway Tolls
  17. \u, \x,0x区别
  18. matlab moler,MATLAB软件创始人Cleve Moler来我校做讲座
  19. 迁出X86架构,你准备好了吗?
  20. rootfs编译步骤2解析

热门文章

  1. nfs 客户端卡死问题
  2. 抓取MBIM PCAP LOG的方法
  3. mobl:针对移动Web开发的“.NET研究”DSL
  4. 爬取网易云音乐两万条评论储存在MySQL服务器上
  5. 从计算云到云计算,云可造化万象
  6. 音乐播放器中期总结(类似于qq音乐的歌词显示)
  7. 【2020校招总结】接受社会的毒打,收获腾讯天美、字节跳动、网易互娱、华为等offer(开发岗)
  8. 春风里,爱水墨画的他
  9. 数据可视化ECharts:ECharts使用
  10. flash下载的别人的在flash中打开显示无法打开受保护的影片怎么回事