漫画:什么是字典序算法
转载自 漫画:什么是字典序算法?
算法题目:
给定一个正整数,实现一个方法来求出离该整数最近的大于自身的“换位数”。
什么是换位数呢?就是把一个整数各个数位的数字进行全排列,从而得到新的整数。例如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.把原来的逆序区域转为顺序
- //主流程,返回最近一个大于自身的相同数字组成的整数。
- public static int[] findNearestNumber(int[] numbers){
- //拷贝入参,避免直接修改入参
- int[] numbersCopy = Arrays.copyOf(numbers, numbers.length);
- //1.从后向前查看逆序区域,找到逆序区域的前一位,也就是数字置换的边界
- int index = findTransferPoint(numbersCopy);
- //如果数字置换边界是0,说明整个数组已经逆序,无法得到更大的相同数字组成的整数,返回自身
- if(index == 0){
- return null;
- }
- //2.把逆序区域的前一位和逆序区域中刚刚大于它的数字交换位置
- exchangeHead(numbersCopy, index);
- //3.把原来的逆序区域转为顺序
- reverse(numbersCopy, index);
- return numbersCopy;
- }
- private static int findTransferPoint(int[] numbers){
- for(int i=numbers.length-1; i>0; i--){
- if(numbers[i] > numbers[i-1]){
- return i;
- }
- }
- return 0;
- }
- private static int[] exchangeHead(int[] numbers, int index){
- int head = numbers[index-1];
- for(int i=numbers.length-1; i>0; i--){
- if(head < numbers[i]){
- numbers[index-1] = numbers[i];
- numbers[i] = head;
- break;
- }
- }
- return numbers;
- }
- private static int[] reverse(int[] num, int index){
- for(int i=index,j=num.length-1; i<j; i++,j--){
- int temp = num[i];
- num[i] = num[j];
- num[j] = temp;
- }
- return num;
- }
- public static void main(String[] args) {
- int[] numbers = {1,2,3,4,5};
- for(int i=0; i<10;i++){
- numbers = findNearestNumber(numbers);
- outputNumbers(numbers);
- }
- }
- //输出数组
- private static void outputNumbers(int[] numbers){
- for(int i : numbers){
- System.out.print(i);
- }
- System.out.println();
- }
这种解法拥有一个高大上的名字:字典序算法。
几点补充:
本漫画纯属娱乐,还请大家尽量珍惜当下的工作,切勿模仿小灰的行为哦。
漫画:什么是字典序算法相关推荐
- 经典算法-并查集、快速排序、字典序算法、二分搜索、牛顿开方法、求质数(筛选法)、编辑距离、滑动窗口、异或求重、长除法
目录 并查集 快速排序 字典序算法 二分搜索 开根号-牛顿开方法 求质数 编辑距离 滑动窗口 异或求重 长除法 并查集 并查集用于解决相同元素集合动态连接 ...
- 【算法入门漫画】:“排序算法” 大总结
冒泡排序: 漫画:什么是冒泡排序? 选择排序: 漫画:什么是选择排序? 插入排序: 漫画:什么是插入排序? 此外还有冒泡排序的变种,鸡尾酒排序: 漫画:什么是鸡尾酒排序? 第三梯队的排序算法有什么共同 ...
- 漫画:呕心泣血算法指导篇(真正的干货,怒怼那些说算法没用的人)
今天是小浩算法"365刷题计划"第70.5天.我们暂停一天,我自己有个很喜欢的话,叫做 "练习 - 坚持 - 总结 - 提高",我们已经练习了 70 天,如果不 ...
- 漫画:一致性hash算法
对于redis.memcached这些分布式缓存系统,需要将数据均匀的分布到缓存服务器集群的不同机器上,就需要使用对缓存的数据的key做hash值计算, 然后在将hash值除以服务器节点的数量取模计算 ...
- 程序员小灰的漫画算法和知识总结,高品质强推!!!
转载自微信号程序员小灰,不定期更新,漫画讲解好评,特来转载. 漫画知识汇总 漫画:深度优先遍历 和 广度优先遍历 漫画:什么是 "图"?(修订版) 漫画:图的 "最短路径 ...
- 全排列的生成算法:字典序法
全排列的生成算法:字典序法 全排列的生成算法 对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来. 字典序法按照字典序求下一个排列的算法 生成给定全排列的下一个排列所 ...
- 漫画:算法如何验证合法数独 | 全世界最难的数独?
今天是小浩算法 "365刷题计划" 第95天 .数独相信在座的各位都玩过,那我们如何使用程序去验证一个 9×9 的数独是有效的呢?一起看下! 01 PART 有效的数独 数独是源自 ...
- 80道漫画图解算法题汇总(0406版本)
各位好,本人自2019年1月以来,连续写了80余篇算法题解(主要针对高频面试题),都采用漫画图解的方式,为了大家查阅方便,我对目录进行了汇总,大家有兴趣的可以收藏一下,以备不时之需.(另外,为了感谢大 ...
- 字典序全排列算法(非递归全排列算法)
非递归全排列算法: 我们先看一个例子. 示例: 1 2 3的全排列如下: 1 2 3 , 1 3 2 , 2 1 3 , 2 3 1 , 3 1 2 , 3 2 1 我们这里是通过字典序法找出来的. ...
最新文章
- matlab ezplot hold,matlab中的ezplot函数
- 30 万奖金悬赏 | CSDN 软件开发精英赛即日启动!
- linux rsync 原理,rsync 同步原理和类别
- 用Socket 打造跨语言跨操作系统的网络MORPG游戏(一)
- 内存不能为读写的解决方法
- 目录行距怎么设置_硕士论文格式设置方法
- Python科学计算
- Perl脚本 — 数字IC验证
- 海洋网络收音机海洋影音盒
- CCD相机参数基本知识
- tungsten replicator oracle,Tungsten Replicator 实验
- 层次分析法简述即其MATLAB代码
- 使用gsds绘制基因结构图_基因结构图的绘制
- java多态的三种表现形式
- 组合数的几种计算方法
- 如何轻松做好设备巡检管理?
- Mono 3.2 测试NPinyin 中文转换拼音代码
- 愚人节恶搞网站谨防遭黑客攻击
- Word2016中添加目录
- linux使用java本地执行cd命令问题
热门文章
- DevC++如何安装自定义头文件并使用
- java8 stream案例分析
- 编程 音量键_盘点市面上那些千元级高逼格的键盘 灯光炫酷 多宏编程
- 火焰效果材质实现_「游戏开发」使用Unity实现魔法火焰效果
- 数据结构 旅游规划(Dijkstra+Dfs)
- CUDA的global内存访问的问题
- Java序列化、反序列化
- Wannafly挑战赛24 无限手套(生成函数)
- HDU - 6959 zoto 莫队 + 值域分块
- Codeforces Round #693 (Div. 3) G. Moving to the Capital dp + 思维