剑指Offer对答如流系列 - 把数组排成最小的数

Posted jefferychenxiao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指Offer对答如流系列 - 把数组排成最小的数相关的知识,希望对你有一定的参考价值。

面试题45:把数组排成最小的数

题目描述

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3, 32, 321},则打印出这3个数字能排成的最小数字321323。

问题分析

之前我们做过字符全排列的习题 剑指Offer对答如流系列 - 字符串的排列,但是将算法思想应用到这一题的话,效果不好,求出所有的组合,再计算出组合的最小值,这效率该多低啊。

我们还要进一步探究,看看有没有不错的规律,供我们使用。

因为数字拼接后的长度一样,拼接后的结果大亦或是小 首先取决于最高位的数字,然后再低位。

既然这样,我们定义一下数学模型:

对于数字m和n,可以拼接成mn和nm,如果mn<nm,我们定义m小于n。反之则相反。利用这个排序规则,从小排到大即可实现题目要求。

  
在求解的时候:拼接m和n,要考虑到大数问题,因此将m和n拼接起来的数字转换成字符串处理。

使用 String.compareTo 方法:

compareTo() 的返回值是int, 它是先比较对应字符的大小(ASCII码顺序)

1、如果字符串相等返回值0

2、如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值(ascii码值)(负值前字符串的值小于后字符串,正值前字符串大于后字符串)

3、如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度.

问题解决

 public String PrintMinNumber(int [] numbers) {
        if(numbers==null || numbers.length<=0) {
            return "";
        }
        ArrayList<String> list = new ArrayList<>();
        for(int number:numbers) {
            list.add(String.valueOf(number));
        }
        list.sort((s1, s2) -> {
            String a = s1 + s2;
            String b = s2 + s1;
            return a.compareTo(b);
        });
        StringBuilder sb= new StringBuilder();
        for(String str:list)
            sb.append(str);
        return sb.toString();
    }

以上是关于剑指Offer对答如流系列 - 把数组排成最小的数的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer系列——32.把数组排成最小的数

剑指 Offer 45. 把数组排成最小的数 剑指 Offer 61. 扑克牌中的顺子 剑指 Offer 40. 最小的k个数

剑指OFFER 把数组排成最小的数

剑指offer-把数组排成最小的数

剑指offer 32.把数组排成最小的数

剑指Offer:把数组排成最小的数45