看题第一感觉:
- IPO(input、process、output)分别为:I:非负 整数的数组; P:拼接数组元素; O:拼接成的最小的数。
- 分析一些例子感觉应该是按照数的最高位排序,再按次高位排序,但对于没有次高位的数来说,那又如何比较呢。例如3和30比较次高位时,3并没有次高位,如果用补0操作的话就无法判断是个位数3补的0,还是原本30就存在的0。所以这个方法弃用。
- 那是不是和整除有关,或者对数进行归一化?——想不通了,看题解思路吧。
题解思路:
对于两个数x和y,如果x+y<y+x
,那么可以看作x<y
(这里的+
代表字符串连接)。
代码思路:
有了以上题解思路,所以如果将数组中元素按照这个比较方式进行从小到大排序,那么数组元素顺序连接即为所求。代码采用快速排序进行数组元素的比较排序。
public String minNumber(int[] nums) {
int left=0, right=nums.length-1;
QuickSort(nums, left, right);
StringBuilder res = new StringBuilder();
for(int num:nums){
//res.append(String.valueOf(num));
res.append(num);
}
return res.toString();
}
public void QuickSort(int[] nums, int left, int right){
if(left >= right) return;
int key = nums[left];
int i=left, j=right;
while(i<j){
while(i<j && Compare(key,nums[j])) j--;
nums[i]=nums[j];
while(i<j && Compare(nums[i],key)) i++;
nums[j]=nums[i];
}
nums[i]=key;
QuickSort(nums,left,j-1);
QuickSort(nums,j+1,right);
}
// 比较的规则
private boolean Compare(int target, int key) {
String x = String.valueOf(target);
String y = String.valueOf(key);
//return Integer.parseInt(x+y)>=Integer.parseInt(y+x);
if((x+y).compareTo(y+x)>=0) {
return true;
}
else return false;
}
}
执行结果:
自己编代码出现的问题&知识点补充
- 强制类型转换 string<——>int
- 快速排序:递归;低位和高位比较之处的区别
- 陷入了无限循环的原因:将
Compare(key,nums[i]))
写成了Compare(nums[i],key))
,这样会导致只考虑了>而不是考虑>= - 比较两个数字连接成的数字的大小:其实完全可以看作是字符串比较,不必转换成int比较,再说长度太长已经超出int范围了。
- 字符串比较:String类中方的compare()方法
- string初始化:
String s="";
- 返回minNumber的字符串连接输出
- StringBuilder-官方文档;StringBuilder-拼接字符串
- java1.8新特性-Lambda表达式理解
- void java.util.Arrays.sort(T[] a, Comparator<? super String> c) ;
- Comparator接口实现自定义排序(与Comparable比较)
- 递归地快速排序的思路:都是先从后往前找
(1)挖坑法:找一个基准元素key,从后往前找比key小的数,找到则将该数换到low的位置上,同时换方向,从前往后找比key大的数,找到则将该数换到high的位置上,重复直到i>=j
,最后将key的值赋给low的位置(其实此时low=high),递归地对数组两侧进行排序。
(2)指针交换法:找一个基准元素key,从后往前找比key小的数,找到则换方向,从前往后找比key大的数,找到则交换二者的值,重复直到i>=j
,最后将key的值赋给high位置,递归地对两侧进行排序
评论区解法1:
public String minNumber(int[] nums) {
String[] strs = new String[nums.length];
for(int i=0;i<nums.length;i++)
strs[i] = String.valueOf(nums[i]);
QuickSort2(strs,0,strs.length-1);
StringBuilder res = new StringBuilder();
for(String str:strs)
res.append(str);
return res.toString();
}
private void QuickSort2(String[] strs, int left, int right) {
if(left>=right) return;
int i = left, j = right;
String key = strs[i];
while(i<j) {
while(i<j && (strs[j]+key).compareTo(key+strs[j]) >= 0)
j--;
strs[i] = strs[j];
while(i<j && (strs[i]+key).compareTo(key+strs[i]) <= 0)
i++;
strs[j] = strs[i];
}
strs[i] = key;
QuickSort2(strs, left, i-1);
QuickSort2(strs, i+1, right);
}
解法2:
public String minNumber(int[] nums) {
String[] strs = new String[nums.length];
for(int i=0;i<nums.length;i++) {
strs[i] = String.valueOf(nums[i]);
}
Arrays.sort(strs,(x,y)->(x+y).compareTo(y+x));
StringBuilder res = new StringBuilder();
for(String s:strs)
res.append(s);
return res.toString();
}