剑指 Offer 45. 把数组排成最小的数 Java自定义排序

简介: 输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

一、题目描述



输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。


示例 1:

输入: [10,2]

输出: "102"


示例 2:

输入: [3,30,34,5,9]

输出: "3033459"


提示:

0 < nums.length <= 100


说明:

输出结果可能非常大,所以你需要返回一个字符串而不是整数

拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0


二、思路讲解


     

我们可以看到,最高位最小的数字应该放在前面;最高位相同的,次高位小的数字在前面。所以我们将数字转为字符串,方便比较每一位。


如何定义大小呢?例如3和30相比,显然将30放在3前面,组成的数字要更小,因为330>303。那么就很显而易见了,比较a、b两个数字“大小”的方式就是 a+b<b+a,则说明a应该放在b前面。

     

于是我们基于快速排序,自定义排序规则。


三、Java代码实现



class Solution {
    public String minNumber(int[] nums) {
        int len = nums.length;
        String []a = new String[len];
        for(int i=0; i<len; i++) {
            a[i] = String.valueOf(nums[i]);
        }
        quickSort(a, 0, len-1);
        StringBuilder res = new StringBuilder("");
        for(int i=0; i<len; i++) {
            res.append(a[i]);
        }
        return res.toString();
    }
    /**
    * 快速排序
    */
    void quickSort(String []a, int i, int j) {
        if(i >= j) {
            return;
        }
        int k = partition(a, i, j);
        quickSort(a, i, k-1);
        quickSort(a, k+1, j);
    }
    /**
    * 自定义规则的partition排序
    */
    int partition(String []a, int i, int j) {
        String position = a[i];
        while(i < j) {
            while(i<j && ((a[j]+position).compareTo((position+a[j]))>=0)) {
                j--;
            }
            a[i] = a[j];
            while(i<j && ((a[i]+position).compareTo((position+a[i]))<=0)) {
                i++;
            }
            a[j] = a[i];
        }
        a[i] = position;
        return i;
    }
}


四、时空复杂度分析



时间复杂度:        O(NlogN) 快速排序的时间复杂度


空间复杂度:        O(N) StringBuilder的长度

相关文章
|
6天前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
|
6天前
|
Java
在 Java 中,如何自定义`NumberFormatException`异常
在Java中,自定义`NumberFormatException`异常可以通过继承`IllegalArgumentException`类并重写其构造方法来实现。自定义异常类可以添加额外的错误信息或行为,以便更精确地处理特定的数字格式转换错误。
|
22天前
|
Java 开发者 Spring
[Java]自定义注解
本文介绍了Java中的四个元注解(@Target、@Retention、@Documented、@Inherited)及其使用方法,并详细讲解了自定义注解的定义和使用细节。文章还提到了Spring框架中的@AliasFor注解,通过示例帮助读者更好地理解和应用这些注解。文中强调了注解的生命周期、继承性和文档化特性,适合初学者和进阶开发者参考。
43 14
|
25天前
|
存储 缓存 算法
Java 数组
【10月更文挑战第19天】Java 数组是一种非常实用的数据结构,它为我们提供了一种简单而有效的方式来存储和管理数据。通过合理地使用数组,我们能够提高程序的运行效率和代码的可读性。更加深入地了解和掌握 Java 数组的特性和应用,为我们的编程之旅增添更多的精彩。
31 4
|
25天前
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
22 2
|
29天前
|
安全 Java
如何在 Java 中创建自定义安全管理器
在Java中创建自定义安全管理器需要继承SecurityManager类并重写其方法,以实现特定的安全策略。通过设置系统安全属性来启用自定义安全管理器,从而控制应用程序的访问权限和安全行为。
|
1月前
|
存储 Java
Java“(array) <X> Not Initialized” (数组未初始化)错误解决
在Java中,遇到“(array) &lt;X&gt; Not Initialized”(数组未初始化)错误时,表示数组变量已被声明但尚未初始化。解决方法是在使用数组之前,通过指定数组的大小和类型来初始化数组,例如:`int[] arr = new int[5];` 或 `String[] strArr = new String[10];`。
|
1月前
|
存储 算法 Java
带你学习java的数组军队列
带你学习java的数组军队列
35 0
|
3月前
|
搜索推荐 算法 Java
经典排序算法之-----选择排序(Java实现)
这篇文章通过Java代码示例详细解释了选择排序算法的实现过程,包括算法的基本思想、核心代码、辅助函数以及测试结果,展示了如何通过选择排序对数组进行升序排列。
经典排序算法之-----选择排序(Java实现)
|
3月前
|
搜索推荐 算法 Java