leetcode-179-最大數-java

題目及測試

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;
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章