转载自 漫画:什么是字典序算法?

算法题目:

给定一个正整数,实现一个方法来求出离该整数最近的大于自身的“换位数”。

什么是换位数呢?就是把一个整数各个数位的数字进行全排列,从而得到新的整数。例如53241和23541。

小灰也不知道这种经过换位的整数应该如何称呼,所以姑且称其为“换位数”。

题目要求写一个方法来寻找最近的且大于自身的换位数。比如下面这样:

输入12345,返回12354

输入12354,返回12435

输入12435,返回12453

小灰发现的“规律”:

输入12345,返回12354

12354 - 12345 = 9

刚好相差9的一次方

输入12354,返回12435

12435 - 12354 = 81

刚好相差9的二次方

所以,每次计算最近的换位数,只需要加上9的N次方即可?

————————————

举一个栗子:

给定1,2,3,4,5这几个数字。

最大的组合:54321

最小的组合:12345

比如给定整数12354,如何找到离它最近且大于它的换位数呢?

为了和原数接近,我们需要尽量保持高位不变,低位在最小的范围内变换顺序。

那么,究竟需要变换多少位呢?这取决于当前整数的逆序区域。

如果所示,12354的逆序区域是最后两位,仅看这两位已经是当前的最大组合。若想最接近原数,又比原数更大,必须从倒数第3位开始改变。

怎样改变呢?12345的倒数第3位是3,我们需要从后面的逆序区域中寻找到刚刚大于3的数字,和3的位置进行互换:

互换后的临时结果是12453,倒数第3位已经确定,这时候最后两位仍然是逆序状态。我们需要把最后两位转变回顺序,以此保证在倒数第3位数值为4的情况下,后两位尽可能小:

这样一来,我们就得到了想要的结果12435。

获得最近换位数的三个步骤:

1.从后向前查看逆序区域,找到逆序区域的前一位,也就是数字置换的边界

2.把逆序区域的前一位和逆序区域中刚刚大于它的数字交换位置

3.把原来的逆序区域转为顺序

  1. //主流程,返回最近一个大于自身的相同数字组成的整数。
  2. public static int[] findNearestNumber(int[] numbers){
  3. //拷贝入参,避免直接修改入参
  4. int[] numbersCopy = Arrays.copyOf(numbers, numbers.length);
  5. //1.从后向前查看逆序区域,找到逆序区域的前一位,也就是数字置换的边界
  6. int index = findTransferPoint(numbersCopy);
  7. //如果数字置换边界是0,说明整个数组已经逆序,无法得到更大的相同数字组成的整数,返回自身
  8. if(index == 0){
  9. return null;
  10. }
  11. //2.把逆序区域的前一位和逆序区域中刚刚大于它的数字交换位置
  12. exchangeHead(numbersCopy, index);
  13. //3.把原来的逆序区域转为顺序
  14. reverse(numbersCopy, index);
  15. return numbersCopy;
  16. }
  17. private static int findTransferPoint(int[] numbers){
  18. for(int i=numbers.length-1; i>0; i--){
  19. if(numbers[i] > numbers[i-1]){
  20. return i;
  21. }
  22. }
  23. return 0;
  24. }
  25. private static int[] exchangeHead(int[] numbers, int index){
  26. int head = numbers[index-1];
  27. for(int i=numbers.length-1; i>0; i--){
  28. if(head < numbers[i]){
  29. numbers[index-1] = numbers[i];
  30. numbers[i] = head;
  31. break;
  32. }
  33. }
  34. return numbers;
  35. }
  36. private static int[] reverse(int[] num, int index){
  37. for(int i=index,j=num.length-1; i<j; i++,j--){
  38. int temp = num[i];
  39. num[i] = num[j];
  40. num[j] = temp;
  41. }
  42. return num;
  43. }
  44. public static void main(String[] args) {
  45. int[] numbers = {1,2,3,4,5};
  46. for(int i=0; i<10;i++){
  47. numbers = findNearestNumber(numbers);
  48. outputNumbers(numbers);
  49. }
  50. }
  51. //输出数组
  52. private static void outputNumbers(int[] numbers){
  53. for(int i : numbers){
  54. System.out.print(i);
  55. }
  56. System.out.println();
  57. }

这种解法拥有一个高大上的名字:字典序算法。

几点补充:

本漫画纯属娱乐,还请大家尽量珍惜当下的工作,切勿模仿小灰的行为哦。

漫画:什么是字典序算法相关推荐

  1. 经典算法-并查集、快速排序、字典序算法、二分搜索、牛顿开方法、求质数(筛选法)、编辑距离、滑动窗口、异或求重、长除法

    目录 ​​​​​​​​​​​​​​ 并查集 快速排序 字典序算法 二分搜索 开根号-牛顿开方法 求质数 编辑距离 滑动窗口 异或求重 长除法 ​​​​​​​ 并查集 并查集用于解决相同元素集合动态连接 ...

  2. 【算法入门漫画】:“排序算法” 大总结

    冒泡排序: 漫画:什么是冒泡排序? 选择排序: 漫画:什么是选择排序? 插入排序: 漫画:什么是插入排序? 此外还有冒泡排序的变种,鸡尾酒排序: 漫画:什么是鸡尾酒排序? 第三梯队的排序算法有什么共同 ...

  3. 漫画:呕心泣血算法指导篇(真正的干货,怒怼那些说算法没用的人)

    今天是小浩算法"365刷题计划"第70.5天.我们暂停一天,我自己有个很喜欢的话,叫做 "练习 - 坚持 - 总结 - 提高",我们已经练习了 70 天,如果不 ...

  4. 漫画:一致性hash算法

    对于redis.memcached这些分布式缓存系统,需要将数据均匀的分布到缓存服务器集群的不同机器上,就需要使用对缓存的数据的key做hash值计算, 然后在将hash值除以服务器节点的数量取模计算 ...

  5. 程序员小灰的漫画算法和知识总结,高品质强推!!!

    转载自微信号程序员小灰,不定期更新,漫画讲解好评,特来转载. 漫画知识汇总 漫画:深度优先遍历 和 广度优先遍历 漫画:什么是 "图"?(修订版) 漫画:图的 "最短路径 ...

  6. 全排列的生成算法:字典序法

    全排列的生成算法:字典序法    全排列的生成算法 对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来.     字典序法按照字典序求下一个排列的算法 生成给定全排列的下一个排列所 ...

  7. 漫画:算法如何验证合法数独 | 全世界最难的数独?

    今天是小浩算法 "365刷题计划" 第95天 .数独相信在座的各位都玩过,那我们如何使用程序去验证一个 9×9 的数独是有效的呢?一起看下! 01 PART 有效的数独 数独是源自 ...

  8. 80道漫画图解算法题汇总(0406版本)

    各位好,本人自2019年1月以来,连续写了80余篇算法题解(主要针对高频面试题),都采用漫画图解的方式,为了大家查阅方便,我对目录进行了汇总,大家有兴趣的可以收藏一下,以备不时之需.(另外,为了感谢大 ...

  9. 字典序全排列算法(非递归全排列算法)

    非递归全排列算法: 我们先看一个例子. 示例: 1 2 3的全排列如下: 1 2 3 , 1 3 2 , 2 1 3 , 2 3 1 , 3 1 2 , 3 2 1 我们这里是通过字典序法找出来的. ...

最新文章

  1. matlab ezplot hold,matlab中的ezplot函数
  2. 30 万奖金悬赏 | CSDN 软件开发精英赛即日启动!
  3. linux rsync 原理,rsync 同步原理和类别
  4. 用Socket 打造跨语言跨操作系统的网络MORPG游戏(一)
  5. 内存不能为读写的解决方法
  6. 目录行距怎么设置_硕士论文格式设置方法
  7. Python科学计算
  8. Perl脚本 — 数字IC验证
  9. 海洋网络收音机海洋影音盒
  10. CCD相机参数基本知识
  11. tungsten replicator oracle,Tungsten Replicator 实验
  12. 层次分析法简述即其MATLAB代码
  13. 使用gsds绘制基因结构图_基因结构图的绘制
  14. java多态的三种表现形式
  15. 组合数的几种计算方法
  16. 如何轻松做好设备巡检管理?
  17. Mono 3.2 测试NPinyin 中文转换拼音代码
  18. 愚人节恶搞网站谨防遭黑客攻击
  19. Word2016中添加目录
  20. linux使用java本地执行cd命令问题

热门文章

  1. DevC++如何安装自定义头文件并使用
  2. java8 stream案例分析
  3. 编程 音量键_盘点市面上那些千元级高逼格的键盘 灯光炫酷 多宏编程
  4. 火焰效果材质实现_「游戏开发」使用Unity实现魔法火焰效果
  5. 数据结构 旅游规划(Dijkstra+Dfs)
  6. CUDA的global内存访问的问题
  7. Java序列化、反序列化
  8. Wannafly挑战赛24 无限手套(生成函数)
  9. HDU - 6959 zoto 莫队 + 值域分块
  10. Codeforces Round #693 (Div. 3) G. Moving to the Capital dp + 思维