1.题目
2.思路
思路:一开始没有任何思路,因为不知道怎么才能保证两个数那个数更小放前面,所以完全不会做....
之后看了一样答案的思路,太妙了啊!!!
正解:两个数,谁应该放前面?? --贪心,每次都把两个数拼接在一起,如果x + y 拼接的数 大于 y + x 拼接的数,那么x就应该放在y的前面。那么继续比较下一个数,不断后移动,所以就类似冒泡排序了。-- n * n --34ms
class Solution {
public String minNumber(int[] nums) {
int n = nums.length;
if(n == 0) return "";
StringBuffer sb = new StringBuffer();
for(int i = 0 ; i < n ; i++){
for(int j = i + 1; j < n ; j++){
if(isBig(nums[i], nums[j])){
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
// System.out.println(nums[i]);
sb.append(nums[i]);
}
return sb.toString();
}
public boolean isBig(int i, int j){
String s1 = i + ""+ j +"";
double d1 = Double.parseDouble(s1);
String s2 = j + ""+ i +"";
double d2 = Double.parseDouble(s2);
// System.out.println(d1 +">>>" + d2);
return d1 > d2;
}
}
改进1 -贪心策略不变,排序可以用快排啊,这样就nlogn --时间是44ms,居然还变多了,神奇。
可能是快排模板写得不太对???
class Solution {
public String minNumber(int[] nums) {
int n = nums.length;
if(n == 0) return "";
// int[]arr = new int[]{0,2,3,1,4,6,-2,7};
quickSort(0, nums.length - 1, nums);
StringBuffer sb = new StringBuffer();
for(int i : nums)
sb.append(i);
// StringBuffer sb = new StringBuffer();
// for(int i = 0 ; i < n ; i++){
// for(int j = i + 1; j < n ; j++){
// if(isBig(nums[i], nums[j])){
// int t = nums[i];
// nums[i] = nums[j];
// nums[j] = t;
// }
// }
// // System.out.println(nums[i]);
// sb.append(nums[i]);
// }
return sb.toString();
// return "";
}
public void quickSort(int low, int high, int[]arr){
int start = low, end = high;
int key = arr[low];
while(start < end){
while(start < end && isBig(arr[end], arr[low]))end--;
while(start < end && isBig2(arr[low], arr[start]))start++;
if(start == end)break;
// 交换大于和小于的位置,便于继续循环
swap(start, end, arr);
}
// 第一次循环结束,交换start 和 最开始的起始位置low的值。
swap(low, start, arr);
// 如果其实位置low < start ,说明还要继续快排。
if(low < start)
quickSort(low, start - 1, arr);
if(high > end)
quickSort(end + 1, high, arr);
}
public void swap(int i, int j, int[]arr){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// i > j , return true
public boolean isBig(int i, int j){
String s1 = i + ""+ j +"";
double d1 = Double.parseDouble(s1);
String s2 = j + ""+ i +"";
double d2 = Double.parseDouble(s2);
// System.out.println(d1 +">>>" + d2);
return d1 >= d2;
}
public boolean isBig2(int i, int j){
String s1 = i + ""+ j +"";
double d1 = Double.parseDouble(s1);
String s2 = j + ""+ i +"";
double d2 = Double.parseDouble(s2);
// System.out.println(d1 +">>>" + d2);
return d1 > d2;
}
}
改进2 -贪心策略不变,排序可以用快排, 然后比较两个数,直接用内置的sort函数(),并且用String数组存储也可以减少时间。
class Solution {
public String minNumber(int[] nums) {
// 内置函数
int n = nums.length;
if(n == 0)return "";
String[]str = new String[n];
for(int i = 0 ; i < n ; i++)
str[i] = String.valueOf(nums[i]);
// 内置函数版本
// Arrays.sort(str, (a, b)->(a + b).compareTo(b + a));
// 自己写
Arrays.sort(str, (a, b)->{
if(Double.parseDouble(a + b) >= Double.parseDouble(b + a))return 1;
else return -1;
});
StringBuffer sb = new StringBuffer();
for(String i : str)
sb.append(i);
return sb.toString();
}
}
3.结果
4.总结
1.如何比较两个数交换后的拼接大小?
可以用Double.parseDouble(i +""+j);
也可以用内置比较字符串大小函数,(a + b).compareTo(b + a);//大概率想不起来
2.自定义排序?
Arrays.sort(nums, (a, b)->{
if(a > b) return 1;
else return -1;
});
3.学会StringBuffer sb = new StringBuffer() (线程安全)
sb.append(str[i]);
sb.toString();