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

简介: 给定一个正整数,实现一个方法来求出离该整数最近的大于自身的“换位数”。什么是换位数呢?就是把一个整数各个数位的数字进行全排列,从而得到新的整数。例如53241和23541。


image.png

image.png

—————  第二天  —————


image.png


image.png



image.png


算法题目:


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


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


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


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


输入12345,返回12354

输入12354,返回12435

输入12435,返回12453



image.png





image.png

小灰发现的“规律”:


输入12345,返回12354

12354 - 12345 = 9

刚好相差9的一次方


输入12354,返回12435

12435 - 12354 = 81

刚好相差9的二次方


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




image.png


image.png


image.png


image.png



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


image.png




image.png

image.png


image.png

image.png


image.png






举一个栗子:


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

最大的组合:54321

最小的组合:12345




image.png


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


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


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



image.png



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


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



image.png



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




image.png

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


image.png

image.png




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


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

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

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


image.png



  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. }


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



image.png


image.png


image.png




几点补充:


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



—————END—————

相关文章
|
8月前
|
算法 Java
【Java每日一题,字典序算法】下一个排列
【Java每日一题,字典序算法】下一个排列
|
3天前
|
算法
时间复杂度与空间复杂度(自漫画算法)
时间复杂度与空间复杂度(自漫画算法)
16 0
|
算法
【漫画算法学习笔记】第二章——2.1数组
本篇博客总结了《漫画算法》第二章的知识点,并将数组的扩容封装成了工具类
79 0
【漫画算法学习笔记】第二章——2.1数组
|
算法
漫画算法题:两数之和与三数之和
我们来举个例子,给定下面这样一个整型数组(假定数组不存在重复元素):我们随意选择一个特定值,比如13,要求找出两数之和等于13的全部组合。 由于12+1 = 13,6+7 = 13,所以最终的输出结果(输出的是下标)如下:
170 0
漫画算法题:两数之和与三数之和
|
算法 Java
漫画:什么是KMP算法?
KMP算法和BF算法的“开局”是一样的,同样是把主串和模式串的首位对齐,从左到右对逐个字符进行比较。
121 0
|
算法 Java
漫画:如何优化 “字符串匹配算法”?
BF算法是如何工作的? 正如同它的全称BruteForce一样,BF算法使用简单粗暴的方式,对主串和模式串进行逐个字符的比较。
150 0
漫画:如何优化 “字符串匹配算法”?
|
算法
漫画:什么是字符串匹配算法?
比较哈希值是什么意思呢? 用过哈希表的朋友们都知道,每一个字符串都可以通过某种哈希算法,转换成一个整型数,这个整型数就是hashcode: hashcode = hash(string) 显然,相对于逐个字符比较两个字符串,仅比较两个字符串的hashcode要容易得多。
122 0
漫画:什么是字符串匹配算法?
|
存储 算法
漫画:Dijkstra 算法的优化
如何求得最短路径的详细节点,而不仅仅是距离?
130 0
漫画:Dijkstra 算法的优化
|
存储 缓存 算法
漫画:什么是LRU算法?
用户信息当然是存在数据库里。但是由于我们对用户系统的性能要求比较高,显然不能每一次请求都去查询数据库。 所以,小灰在内存中创建了一个哈希表作为缓存,每次查找一个用户的时候先在哈希表中查询,以此提高访问性能。
143 0
漫画:什么是LRU算法?
|
算法
漫画:如何实现抢红包算法?
发出一个固定金额的红包,由若干个人来抢,需要满足哪些规则?所有人抢到金额之和等于红包金额,不能超过,也不能少于。每个人至少抢到一分钱。要保证所有人抢到金额的几率相等。
164 0
漫画:如何实现抢红包算法?