目录
把数组排成最小的数
描述
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例 1
输入
[10,2]
输出
"102"
示例 2
输入
[3,30,34,5,9]
输出
"3033459"
提示
0 < nums.length <= 100
说明
输出结果可能非常大,所以你需要返回一个字符串而不是整数
拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0
方法:自定义排序
此题要求拼接起来的是最小数字,本质上是一个排序问题,我们将数组的里面的数字按照某种规则排序好那么拼接得到的就是最小数字。
我们定义排序的大小规则为:
- 如果拼接字符串,则x大于y
- 如果拼接字符串,则x小于y
如果x小于y,那么我们就要在数组中将x放在y的左边,大于的话则将x放在y的右边。
我自己就写了个选择排序,然后写了个自定义的比较大小的方法。
class Solution {
public String minNumber(int[] nums) {
for (int i = 0; i < nums.length-1; i++) {
for (int j = i+1; j < nums.length; j++) {
if (myCompare(nums[i],nums[j])){//如果nums[i]大于nums[j],那么就将i放到j的右边
int temp=nums[i];//交换两个数
nums[i]=nums[j];
nums[j]=temp;
}
}
}
StringBuffer res=new StringBuffer();
for (int i = 0; i < nums.length; i++) {
res.append(nums[i]);
}
return res.toString();
}
public boolean myCompare(int x, int y){
String digitXY=(""+x+y);
String digitYX=(""+y+x);
if (digitXY.length()!=digitYX.length()){
return digitXY.length()>digitYX.length()?true:false;
}else{
int len=digitXY.length();//获取当前字符的位数
for (int i = 0; i < len; i++) {//从高位开始比较
if (digitXY.charAt(i)>digitYX.charAt(i)){
return true;//如果当前位XY大于YX,则认为X大于Y
}else if (digitXY.charAt(i)<digitYX.charAt(i)){
return false;//如果当前位XY小于YX,则认为X小于Y
}else{
continue;//如果两个位数相等,则比较下一位
}
}
}
return true;//如果所有位数都比较完了都相等,则认为相等,我们这里认为定义X>Y
}
}
官方用的是Arrays.sort()方法进行排序,这里比较巧妙用的是compareTo方法比较的字符串,
其比较的规则是:从字符串的第一位开始比较,直到字符不同时,返回他们ascii码的差值。
因为这里x+y和y+x的位数相同,所以不会出现"110"比"12"小的这种情况。
class Solution {
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]);//将值全部转换为String类型
Arrays.sort(strs, (x, y) -> (x + y).compareTo(y + x));//compareTo比较两个String类型
StringBuilder res = new StringBuilder();
for(String s : strs)
res.append(s);
return res.toString();
}
}