输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例 1:
输入: [10,2]
输出: "102"
示例 2:
输入: [3,30,34,5,9]
输出: "3033459"
提示:
- 0 < nums.length <= 100
说明:
- 输出结果可能非常大,所以你需要返回一个字符串而不是整数
- 拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0
分析:
方法:快速排序+内置函数
如果不管那些首数字相同的数字,那么只要数组是升序的,那么这个数组拼接的数就是就小的树,利用 快速排序 就可以解决,关键在于如何比较那些首数字相同的数字。
比如 3 和 30,30 一定是在 3 前面,因为 303 < 330,既然如此,那我们是不是可以把两个数拼接起来和它反向拼接比较,然后交换呢?而 Java 中的内置函数 compareTo() 正好可以做到,这个内置函数会从首字符开始比较,如果俩个字符串的首字符不一样,就返回俩个字符的差值,一样就继续比较下一个。
时间复杂度:O(n*log n)
空间复杂度:O(n)
class Solution {
public String minNumber(int[] nums) {
//整型转化为字符串型
String[] str = new String[nums.length];
for(int i = 0; i < nums.length; ++i){
str[i] = String.valueOf(nums[i]);
}
quickSort(str, 0, nums.length-1);
StringBuilder sb = new StringBuilder();
//拼接数字
for(String s: str){
sb.append(s);
}
return sb.toString();
}
//快速排序
public void quickSort(String[] nums, int start, int end){
if(start >= end){
return;
}
//定义双指针,辅助变量
int i = start, j = end;
String temp = nums[start];
//遍历
while(i < j){
while(i < j && compare(temp, nums[j])){
j--;
}
while(i < j && compare(nums[i], temp)){
i++;
}
//交换
String tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
nums[start] = nums[i];
nums[i] = temp;
//继续遍历
quickSort(nums, i+1, end);
quickSort(nums, start, j-1);
}
//比较方法
public boolean compare(String a, String b){
return (a + b).compareTo(b + a) <= 0;
}
}
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof