把数组排成最小的数

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

思路

Collections.sort()排序。
时间复杂度O(nlgn),空间复杂度O(n)。

compareTo代码

import java.util.ArrayList;
import java.util.Collections;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        ArrayList<String> arrayList = new ArrayList<String>();
        for(int i : numbers){
            arrayList.add( i + "" );
        }
        Collections.sort(arrayList, (s1,s2)->(s1+s2).compareTo(s2+s1));
        StringBuilder stringBuilder2 = new StringBuilder();
        for(String s : arrayList){
            stringBuilder2.append(s);
        }
        return stringBuilder2.toString();
    }
}

手写compare代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        ArrayList<String> arrayList = new ArrayList<String>();
        for(int i : numbers){
            arrayList.add( i + "" );
        }
        Collections.sort(arrayList, new Comparator<String>() {
            public int compare(String s1, String s2) {
                int i = 0, j = 0;
                while(i < s1.length() || j < s2.length()) {
                    if(i == s1.length())    i = 0;
                    if(j == s2.length())    j = 0;
                    if(s1.charAt(i) < s2.charAt(j)) return -1;
                    if(s1.charAt(i) > s2.charAt(j)) return 1;
                    i++; j++;
                }
                return 0;
            }
        });
        StringBuilder stringBuilder2 = new StringBuilder();
        for(String s : arrayList){
            stringBuilder2.append(s);
        }
        return stringBuilder2.toString();
    }
}

笔记

手写compare比直接构造两个字符串进行compareTo在时间空间复杂度上都有所区别。

  • 手写compare运行时间内存大致为:34ms 9748k
  • 用compareTo运行时间内存大致为:233ms 16016k

在compareTo前构造了两个拼接字符串,这是多余的消耗。
根据String类的compareTo源码,在函数内部又将两个String转成了字符数组,又是多余的消耗。
而这些消耗都可以通过自己手写compare规则避免,整个算法主要在于sort,而sort又主要在于compare。

compareTo源码:

    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }
原文地址:https://www.cnblogs.com/ustca/p/12356460.html