剑指Offer面试题-45 把数组排成最小的数(自定义排序)

题目描述

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

示例 1:

输入: [10,2]
输出: "102"

示例 2:

输入: [3,30,34,5,9]
输出: "3033459"

提示:

0 < nums.length <= 100

说明:

输出结果可能非常大,所以你需要返回一个字符串而不是整数
拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0

题解

自定义一个排序规则,来对数组进行排序,最后拼接。

常规做法是将两个比较的字符串ab拼接成a + bb + a。然后逐位比较大小。
但每次比较都要进行字符串的拼接,很耗时间。所以对这个操作做了优化。

class Solution {
    public String minNumber(int[] nums) {
        if (nums.length == 0) {
            return "";
        }

        String [] strs = new String[nums.length];
        for (int i = 0 ; i < nums.length ; i++) {
            strs[i] = Integer.toString(nums[i]);
        }

        Arrays.sort(strs, new Comparator<String>()
		{
			@Override
			public int compare(String s1, String s2)
			{
				int len = s1.length() + s2.length();
				for (int i = 0 ; i < len ; i++)
				{
					// 优化s1 + s2
					char c1 = getChar(s1, s2, i);
					char c2 = getChar(s2, s1, i);
					if (c1 < c2) {
						return -1;
					} else if (c1 > c2) {
						return 1;
					}
				}
				return 0;
			}

			private char getChar(String s1, String s2, int i)
			{
				if (i < s1.length()) {
					return s1.charAt(i);
				} else {
					return s2.charAt(i - s1.length());
				}
			}
		});

        StringBuilder sb = new StringBuilder();
        for (String str : strs) {
            sb.append(str);
        }
        return sb.toString();
    }
}

时间复杂度: O ( l o g ( N ) ) O(log(N)) O(log(N))
N N N为数组长度。快速排序耗时 O ( l o g ( N ) ) O(log(N)) O(log(N)),内置的比较操作因为字符串是整数类型转化的,长度有限制,所以认为在常数级时间完成比较。

空间复杂度: O ( N ) O(N) O(N)
字符串数组占空间 O ( N ) O(N) O(N)
剑指Offer面试题-45 把数组排成最小的数(自定义排序)_第1张图片

你可能感兴趣的:(算法)