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

题目描述

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

思路

思路1:求数组中所有数字的全排列,类似于“字符串的排列”,然后把每个排列拼起来,求最小值。      (时间复杂度很高,n个数字有n!个排列)
 
思路2:自定义排序规则。本题核心 -> 「如何对字符串数组进行排序」
 
  • 对于数字m和n,可以拼接成mn和nm,如果mn<nm,我们定义m小于n。反之则相反。利用这个排序规则,从小排到大即可实现题目要求。
  • 拼接m和n时,要考虑到大数问题,因此将m和n拼接起来的数字转换成字符串处理。因为mn和nm的字符串位数相同,因此它们的大小只需要按照字符串大小的比较规则就可以了。
  • 具体实现:重写compare(Object o1, Object o2)方法来规定比较规则。

解法1(利用Arrays.sort())

import java.util.*;

public class Solution {
    // 利用Arrays.sort()排序
    //运行时间:135ms  占用内存:14720k
    public String PrintMinNumber(int [] numbers) {
        if (numbers == null || numbers.length <= 0)
            return "";
        //Step01 int类型数组转化为 String类型的数组
        String[] arr = new String[numbers.length];
        for (int i = 0; i < numbers.length; i++) {
            arr[i] = String.valueOf(numbers[i]);
            //arr[i] = numbers[i] + "";        // 与String相加 也可以把int转化为String
        }
        //Step02关键: 对String类型数组排序
        // 使用lamda表达式Arrays.sort(arr, (参数列表) -> {返回语句});
        Arrays.sort(arr, (o1, o2) -> {
            return (o1 + o2).compareTo(o2 + o1); //升序 两个字符串拼接,把拼接的结果较小的排到前面
        });
//        Arrays.sort(arr, new Comparator<String>() {
//            @Override
//            public int compare(String o1, String o2) {
//                return (o1 + o2).compareTo(o2 + o1); //升序 两个字符串拼接,把拼接的结果较小的排到前面
//            }
//        });
        //Step3 String[]数组 转化为 String类型
        StringBuilder sb = new StringBuilder();
        for (String s : arr){
            sb.append(s);
        }
        return sb.toString();
    }
}

 

解法2(利用list.sort() 或 Collections.sort())

import java.util.*;

public class Solution {
    // 利用list.sort() 或 Collections.sort()
    // list.sort() 运行时间:93ms 占用内存:15188k
    // Collections.sort() 运行时间:87ms 占用内存:15148k
    public String PrintMinNumber(int [] numbers) {
        if (numbers == null || numbers.length <= 0)
            return "";
        ArrayList<String> list = new ArrayList<>();
        for (int num : numbers)
            list.add(String.valueOf(num));
//        Collections.sort(list,(o1, o2) -> {
//            return (o1+o2).compareTo(o2+o1);
//        });
        list.sort((o1, o2) -> {
            return (o1+o2).compareTo(o2+o1);
        });
        StringBuilder sb = new StringBuilder();
        for (String s : list)
            sb.append(s);
        return sb.toString();
    }
}

 

 

收获

(1)如果把两个int型的整数拼接起来得到的数字可能会超过int型数字能表达的范围,导致数字溢出。 解决方案是「用字符串表示数字」,这样就能简捷得解决大数问题了~

(2)会区分Comparable、CompareTo()、Comparator和compare()

  • Comparable是一个接口,其中可以重写CompareTo()方法;
  • Comparator是一个比较器类:可以重写其中compare(Object o1, Object o2)方法;Comparator对象可以被传入Arrays.sort()、PriorityQueue()中
 
 
参考:
 
posted @ 2020-08-19 11:52  不学无墅_NKer  阅读(189)  评论(0编辑  收藏  举报