題目及測試
package pid179;
/*最大數
給定一組非負整數,重新排列它們的順序使之組成一個最大的整數。
示例 1:
輸入: [10,2]
輸出: 210
示例 2:
輸入: [3,30,34,5,9]
輸出: 9534330
說明: 輸出結果可能非常大,所以你需要返回一個字符串而不是整數。
*/
public class main {
public static void main(String[] args) {
int[][] testTable = {{999999998,999999997,999999999},{3,30,34,5,9}};
for (int[] ito : testTable) {
test(ito);
}
}
private static void test(int[] ito) {
Solution solution = new Solution();
String rtn;
long begin = System.currentTimeMillis();
for (int i = 0; i < ito.length; i++) {
System.out.print(ito[i]+" ");
}//開始時打印數組
System.out.println();
rtn = solution.largestNumber(ito);//執行程序
long end = System.currentTimeMillis();
System.out.println("rtn=" + rtn);
System.out.println("耗時:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功,5ms,極快)
先對數組進行排序
a+b>b+a,則a大,如3 12 3*100+12 12*10+3,312>123,則3>123,
然後按這種排序方法,從大到小一次放到最前面
package pid179;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Solution {
public String largestNumber(int[] nums) {
List<Integer> list = new ArrayList<Integer>(nums.length);
for(int num:nums){
list.add(num);
}
Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer a, Integer b)
{
return whoFirstWhoBig(a,b);
}
});
StringBuilder result = new StringBuilder();
boolean allZero = true;
for(int i=list.size()-1;i>=0;i--){
int num = list.get(i);
result.append(num);
if(num !=0){
allZero = false;
}
}
if(allZero){
return "0";
}
return result.toString();
}
// length爲10
private int[] num10s = new int[]{1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
/** a與b,a+b>b+a,則a大
* @param a
* @param b
* @return
*/
private int whoFirstWhoBig(Integer a, Integer b)
{
if(a == 0){
return -1;
}
if(b == 0){
return 1;
}
// 3 12 3*100+12 12*10+3
int indexA = 0;
int indexB = 0;
for(int i=0;i<10;i++){
if(a >= num10s[i]){
indexA = i;
}else{
break;
}
}
for(int i=0;i<10;i++){
if(b >= num10s[i]){
indexB = i;
}else{
break;
}
}
long aB = (long)a * num10s[indexB] * 10 +b;
long bA = (long)b * num10s[indexA] * 10 +a;
if(aB > bA){
return 1;
}else{
return -1;
}
}
}
解法2(別人的)
爲了構建最大數字,我們希望越高位的數字越大越好。
首先,我們將每個整數變成字符串。然後進行排序。
如果僅按降序排序,有相同的開頭數字的時候會出現問題。比方說,樣例 2 按降序排序得到的數字是 9534330 ,然而交換 3 和 30 的位置可以得到正確答案 9534330 。因此,每一對數在排序的比較過程中,我們比較兩種連接順序哪一種更好。我們可以證明這樣的做法是正確的:
假設(不是一般性),某一對整數 a 和 b ,我們的比較結果是 a 應該在 b 前面,這意味着 ab>ba 。如果排序結果是錯的,說明存在一個 c , b 在 c 前面且 c 在 a 的前面。這產生了矛盾,因爲 ab>ba 和 bc>cb 意味着 ac>ca 。換言之,我們的自定義比較方法保證了傳遞性,所以這樣子排序是對的。
一旦數組排好了序,最“重要”的數字會在最前面。有一個需要注意的情況是如果數組只包含 0 ,我們直接返回結果 0 即可。否則,我們用排好序的數組形成一個字符串並返回。
class Solution {
private class LargerNumberComparator implements Comparator<String> {
@Override
public int compare(String a, String b) {
String order1 = a + b;
String order2 = b + a;
return order2.compareTo(order1);
}
}
public String largestNumber(int[] nums) {
// Get input integers as strings.
String[] asStrs = new String[nums.length];
for (int i = 0; i < nums.length; i++) {
asStrs[i] = String.valueOf(nums[i]);
}
// Sort strings according to custom comparator.
Arrays.sort(asStrs, new LargerNumberComparator());
// If, after being sorted, the largest number is `0`, the entire number
// is zero.
if (asStrs[0].equals("0")) {
return "0";
}
// Build largest number from sorted array.
String largestNumberStr = new String();
for (String numAsStr : asStrs) {
largestNumberStr += numAsStr;
}
return largestNumberStr;
}
}