题目如下:
题目说的是用数组中的元素拼接成一个新的数,求这个数的最大值。
考虑最简单的情况:数组中的数都是一位数,如nums[1,5,8],要拼接出一个尽可能大的数,首先对其进行排序,为8,5,1,然后将其拼接起来,即为所求(851)。同理,这道题也可以用排序解决,只不过要重新定义一种排序的规则。
排序的规则定义了如何判断两个数的大小(传统意义上,从高位开始依次比较),对于该题,排序规则为:
对于数字m和n,可以拼接成两个数,mn和nm,如果mn>nm,则应该将m排在n前面,也可以理解为m>n。按照这种规则将nums中的元素排好,之后直接进行拼接就行。不难证明,在这种规则下,得到的数就是满足要求的数。按照定义的规则,只要将nums降序排列,再进行拼接就可以了。因此,该题有两种思路。一是自己写排序函数(插入,冒泡,选择),将数组降序输出,二是调用内置的sort函数,但要做一些修改,设置规则。
方法一:
class Solution {
public String largestNumber(int[] nums) {
if(nums == null){
return null;
}
StringBuilder sb = new StringBuilder();
String pre,last;
int temp;
for(int i = 1; i < nums.length; i++){
for(int j = 0; j < nums.length-i; j++){
pre = nums[j] + "" + nums[j+1]; //转换成字符串的形式
last = nums[j+1] + "" + nums[j];
if(pre.compareTo(last) < 0){ //比较组合之后的ab和ba
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}//冒泡算法,小的值往右边冒
}
}
for(int i=0;i<nums.length;i++)//拼接
sb.append(nums[i]);
String s=sb.toString();
while(s.charAt(0)=='0'&&s.length()>1)
s=s.substring(1);
return s;
}
}
方法二:s2>s1时返回1,等于时返回0,小于时返回-1;当comp返回1时,sort交换形参位置
class Solution {
/*
String s1 = "9";
String s2 = "31";
String case1 = s1 + s2; // 931
String case2 = s2 + s1; // 319
*/
public String largestNumber(int[] num) {
if(num == null || num.length == 0)
return "";
// Convert int array to String array, so we can sort later on
String[] s_num = new String[num.length];
for(int i = 0; i < num.length; i++)
s_num[i] = String.valueOf(num[i]);
// Comparator to decide which string should come first in concatenation
Comparator<String> comp = new Comparator<String>(){
@Override
public int compare(String str1, String str2){
String s1 = str1 + str2;
String s2 = str2 + str1;
return s2.compareTo(s1); // reverse order here, so we can do append(later,
//s2>s1时返回1,等于时返回0,小于时返回-1;当comp返回1时,sort交换形参位置
}
};
Arrays.sort(s_num, comp);
// An extreme edge case by lc, say you have only a bunch of 0 in your int array
if(s_num[0].charAt(0) == '0')
return "0";
StringBuilder sb = new StringBuilder();
for(String s: s_num)
sb.append(s);
return sb.toString();
}
}