剑指Offer:把数组排成最小的数

题目

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

解一:
一个想法是:其实就是对数组进行排序。要保证拼接起来的数最小,排序的规则要保证:
如果首位不同:则首位小的数排在前面;
如果首位相同:记首位为X。则比较后一位,后一位较小的排在前面;若相同,则依次比较后面的位数;
如果比较时,其中一个数a的位数小于另一个数b,则在比较某一位时,存在a已经没有数字可以比较的情况。
此时:判断b的该位数字,如果该位数字小于X(首位数字),则该数字应该排在前面;
如果大于X,则该数字应该排在后面;
如果等于X,则判断b的后一位数字,依次类推。

想bb的话:em不好想,太绕了;也不好写代码。写了个鬼代码如下,轻喷。
可以学习到的地方:
1)关于Arrays.sort(T[], Comparator());的使用:不能传int[]数组,没办法进行排序;必须转换成包装类Integer
2)import java.util.Comparator;
import java.util.Arrays;

    public String PrintMinNumber(int [] numbers) {
    	Integer[] dup = new Integer[numbers.length];
    	for(int i = 0; i < numbers.length; i++) {
    		dup[i] = numbers[i];
    	}
        Arrays.sort(dup, new Comparator<Integer>(){
            @Override
            public int compare(Integer a, Integer b){
                String str1 = a.toString();
                String str2 = b.toString();
                int ch1 = Integer.parseInt(str1.substring(0, 1));
                int ch2 = Integer.parseInt(str2.substring(0, 1));
                if(ch1 != ch2) return ch1 - ch2;
                str1 = str1.substring(1);
                str2 = str2.substring(1);
                while(str1.length() > 0 && str2.length() > 0){
                    int tmp1 = Integer.parseInt(str1.substring(0, 1));
                    int tmp2 = Integer.parseInt(str2.substring(0, 1));
                    if(tmp1 != tmp2) return tmp1 - tmp2;
                    str1 = str1.substring(1);
                    str2 = str2.substring(1);
                }
                if(str1.length() > 0){
                    while(str1.length() > 0){
                        int tmp1 = Integer.parseInt(str1.substring(0, 1));
                        if(tmp1 == ch1){
                            str1 = str1.substring(1);
                        }else{
                            return tmp1 - ch1;
                        }
                    }
                    return 0;
                }else{
                    while(str2.length() > 0){
                        int tmp1 = Integer.parseInt(str2.substring(0, 1));
                        if(tmp1 == ch1){
                            str2 = str2.substring(1);
                        }else{
                            return ch1 - tmp1;
                        }
                    }
                    return 0;
                }
            }
        });
        StringBuffer sb = new StringBuffer();
        for(int i = 0;i < dup.length; i++){
            sb.append(dup[i]);
        }
        return sb.toString();
    }

解二:
排序思路是:对于两个数字a和b,如32和321,将其进行拼接;

  • 如果ab<ba:即32132 < 32321,则a应该排在前面
  • 如果ab>ba:则b应该排在前面
  • 如果ab=ba:则两个谁在前面都可以。
    public String PrintMinNumber(int [] numbers) {
        String[] strs = new String[numbers.length];
        for(int i = 0; i < numbers.length; i++){
            strs[i] = String.valueOf(numbers[i]);
        }
        Arrays.sort(strs, new Comparator<String>(){
            public int compare(String str1, String str2){
                String tmp1 = str1 + str2;
                String tmp2 = str2 + str1;
                return tmp1.compareTo(tmp2);
            }
        });
        StringBuffer sb = new StringBuffer();
        for(int i = 0;i < strs.length; i++){
            sb.append(strs[i]);
        }
        return sb.toString();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值