目录
题目描述
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例 1:
输入: [10,2]
输出: "102"
示例 2:
输入: [3,30,34,5,9]
输出: "3033459"
解题思路
刚开始拿到这个题的时候,我的思路是将所有的元素用 Arrays.sort() 进行排序,但是经过排序后的数组是根据整体的大小来安排的,例如 “8 < 30”,但由题目可知,在排序时应该要求8在30的前面。因此我考虑使用 String类型进行排序,在排序后时可以按照当前元素的每个字符进行排序,但是会遇到 “3 < 30”这样的情况,由题意可知20应该在3 的前面,所以我们知道,在进行 sort 排序时需要重写排序规则。
因此重写的规则是:如果 X + Y > Y + X,那么就需要把Y 放到X的前面,在排序时可以重写快排,因此这样的时间复杂度小。
代码展示
在面试手撕时建议重写快排方法
class Solution {
public String minNumber(int[] nums) {
String ans = "";
String[] check = new String[nums.length];
for(int i = 0; i < nums.length; i++) {
check[i] = nums[i] + "";
}
quickSort(check,0,check.length - 1);
for(String str : check) {
ans += str;
}
return ans;
}
public void quickSort(String[] check, int start, int end) {
if(start >= end) {
return;
}
int pivot = quickIndex(check,start,end);
quickSort(check,start,pivot-1);
quickSort(check,pivot+1,end);
}
public int quickIndex(String[] check, int start, int end) {
int pivot = end;
int i = start;
for(int j = start; j < end; j++) {
if((check[j] + check[pivot]).compareTo(check[pivot] + check[j]) < 0) {
if(i != j) {
swap(check,i,j);
}
i++;
}
}
swap(check,i,pivot);
return i;
}
public void swap(String[] check, int start, int end) {
String t = check[start];
check[start] = check[end];
check[end] = t;
}
}
在笔试时建议使用系统自带的排序方法
public String minNumber(int[] nums) {
String ans = "";
String[] check = new String[nums.length];
for(int i = 0; i < nums.length; i++) {
check[i] = nums[i] + "";
}
//quickSort(check,0,check.length - 1);
Arrays.sort(check,(x,y) -> (x+y).compareTo(y+x));
for(String str : check) {
ans += str;
}
return ans;
}