剑指 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的长度

相关文章
|
8月前
|
存储 缓存 Java
Java数组全解析:一维、多维与内存模型
本文深入解析Java数组的内存布局与操作技巧,涵盖一维及多维数组的声明、初始化、内存模型,以及数组常见陷阱和性能优化。通过图文结合的方式帮助开发者彻底理解数组本质,并提供Arrays工具类的实用方法与面试高频问题解析,助你掌握数组核心知识,避免常见错误。
|
6月前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
266 4
|
7月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
8月前
|
Java 数据库 C++
Java异常处理机制:try-catch、throws与自定义异常
本文深入解析Java异常处理机制,涵盖异常分类、try-catch-finally使用、throw与throws区别、自定义异常及最佳实践,助你写出更健壮、清晰的代码,提升Java编程能力。
|
9月前
|
监控 Java API
Java语言按文件创建日期排序及获取最新文件的技术
这段代码实现了文件创建时间的读取、文件列表的获取与排序以及获取最新文件的需求。它具备良好的效率和可读性,对于绝大多数处理文件属性相关的需求来说足够健壮。在实际应用中,根据具体情况,可能还需要进一步处理如访问权限不足、文件系统不支持某些属性等边界情况。
413 14
|
9月前
|
存储 Java 索引
java 数组
在 Java 中,数组是一种数据结构,用于存储多个相同类型的数据元素。数组的大小一旦创建后就不能改变,因此它是固定长度的。Java 数组是一种 对象,即使它存储的值是基本类型(如 int、double 等),它也是一个对象引用。
217 0
|
9月前
|
XML 人工智能 Java
java通过自定义TraceId实现简单的链路追踪
本文介绍了如何在Spring Boot项目中通过SLF4J的MDC实现日志上下文traceId追踪。内容涵盖依赖配置、拦截器实现、网关与服务间调用的traceId传递、多线程环境下的上下文同步,以及logback日志格式配置。适用于小型微服务架构的链路追踪,便于排查复杂调用场景中的问题。
432 0
|
前端开发 Java
java前端:删除数组中指定元素的方法
java前端:删除数组中指定元素的方法
310 1
|
存储 Java 索引
Java快速入门之数组、方法
### Java快速入门之数组与方法简介 #### 一、数组 数组是一种容器,用于存储同种数据类型的多个值。定义数组时需指定数据类型,如`int[]`只能存储整数。数组的初始化分为静态和动态两种: - **静态初始化**:直接指定元素,系统自动计算长度,如`int[] arr = {1, 2, 3};` - **动态初始化**:手动指定长度,系统给定默认值,如`int[] arr = new int[3];` 数组访问通过索引完成,索引从0开始,最大索引为`数组.length - 1`。遍历数组常用`for`循环。常见操作包括求和、找最值、统计特定条件元素等。
下一篇
开通oss服务