将给定的数组组成最大的数 Largest Number

问题:

Given a list of non negative integers, arrange them such that they form the largest number.

For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.

Note: The result may be very large, so you need to return a string instead of an integer.

解决:https://segmentfault.com/a/1190000003813982

① 要拼成最大数,我们只要让较大的数排在前面,较小的数排在后面就行。然而如何对原数组排序呢?当比较一位数时,直接比较大小就行了,但对于多位数呢

1. 个位数越大的越靠前,如例子中9在5, 4, 3之前;

2. 个位相同的再看十位,如例子中34应当在30之前;

3. 难点是位数不等时,先后关系怎么确定?如例子中3应当放在30和34之前、之后还是中间? 结果是3放在了34和30中间,为什么呢?这是因为34的个位上的4比3大,所以34在3之前,而30个位上的0比3小,所以30在3之后。

4. 【规律】对于那些有包含关系的数,如1234包含12,那么只需看1234比12多出的部分34比12大还是小。只是这样需要考虑的情况太复杂了,如565656和56……

5. 可以换一下思路,要想比较两个数在最终结果中的先后位置,何不直接比较一下不同组合的结果大小? 举个例子:要比较3和34的先后位置,可以比较334和343的大小,而343比334大,所以34应当在前。     这样,有了比较两个数的方法,就可以对整个数组进行排序。然后再把排好序的数拼接在一起就好了

6【注】如果排序后第一个数是0,则直接返回0,因为后面的数只有可能是0了。

class Solution{//120ms
    public static String largestNumber(int[] nums){
        int len = nums.length;
        if (len < 1) {
            return "";
        }
        String[] strs = new String[len];
        for (int i = 0;i < len ;i ++ ) {
            strs[i] = String.valueOf(nums[i]);
        }
        Arrays.sort(strs,new Comparator<String>(){
            public int compare(String a,String b){//a:30,b:3
                String ab = a.concat(b);
                String ba = b.concat(a);
                //将 Number 对象与方法的参数进行比较
                //如果指定的数与参数相等返回0。
                //如果指定的数小于参数返回 -1。
                //如果指定的数大于参数返回 1。
                return ba.compareTo(ab);

            }
        });//降序排列
        String res = "";
        for (int i = 0;i < len;i ++ ) {//拼接字符串
            res = res.concat(strs[i]);
        }
        int i = 0;
        while(i < len && res.charAt(i) == '0'){//跳过前面的0
            i ++;
        }
        if (i == len) {//如果所有的结果字符串都为0,则返回0即可。
            return "0";
        }
        return res.substring(i);//返回有效的字符串
    }
}

对0的处理进行了优化!

public class Solution{ //115ms
    public static String largestNumber(int[] nums){
        String res = "";
        String[] str = new String[nums.length];
        for (int i = 0;i < nums.length;i ++){
            str[i] = String.valueOf(nums[i]);
        }
        Arrays.sort(str,(o1,o2) -> {
            String ab = o1.concat(o2);
            String ba = o2.concat(o1);
            return ba.compareTo(ab);
        });
        for (String s : str){
            res += s;
        }
        if (res.charAt(0) == '0'){
            return "0";
        }

        return res;
    }
}

使用StringBuilder保存结果

class Solution{//111ms
    public static String largestNumber(int[] nums){
        int len = nums.length;
        String[] strs = new String[len];
        for (int i = 0;i < len;i ++){
            strs[i] = String.valueOf(nums[i]);
        }
        Arrays.sort(strs, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                String ab = a.concat(b);
                String ba = b.concat(a);
                return ba.compareTo(ab);
            }
        });
        StringBuilder sb = new StringBuilder();
        for (int i = 0;i < len;i ++){
            sb.append(strs[i]);
        }
        int i = 0;
        String res = sb.toString();
        while(i < len && res.charAt(i) == '0'){
            i ++;
        }
        if(i == len) return "0";
        return res;
    }
}

相似的,将数组转换为Integer类型,然后再进行比较。

class Solution { //121ms
    public String largestNumber(int[] nums) {
        Integer[] tmp = new Integer[nums.length];//将数值转换为Number类的子类,以便于重载比较
        for (int i = 0;i < nums.length;i ++){//将数值放入Integer数组方便排序
            tmp[i] = nums[i];
        }
        Arrays.sort(tmp, new Comparator<Integer>() {
            @Override
            public int compare(Integer num1, Integer num2) {
                String str1 = String.valueOf(num1);//将Integer类型的数转换为String类型
                String str2 = String.valueOf(num2);
                return (str2 + str1).compareTo(str1 + str2);//(str1 + str2).compareTo(str2 + str1);---升序            }
        });//排序之后的结果[3, 30, 34, 5, 9] ---> [9, 5, 34, 3, 30]
        if (tmp[0] == 0){
            return "0";
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0;i < nums.length;i ++){
            sb.append(tmp[i]);
        }
        return sb.toString();
    }
}

【注】

compareTo() 方法用于将 Number 对象与方法的参数进行比较。可用于比较 Byte, Long, Integer等。

该方法用于两个相同数据类型的比较,两个不同类型的数据不能用此方法来比较。

转载于:https://my.oschina.net/liyurong/blog/1570703

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值