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

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

tips:

1. Compare(o1,o2),这里默认升序,也就是return o1-o2; 只有返回-1,才需要交换o1,o2。所以若o1<o2,则o1-o2 返回-1,不需要交换,所以还是o1,o2的顺序(升序)。

2. Arrays.sort()使用快排。

3. 用stringBuilder.append() 再.toString() 比 string/int/char+""  转为String好。虽然麻烦了点。

代码:

法1:讨论区大佬的方法,由c++改为java。好方法,但是还没想好怎么表述这个compare。

//    新的比较方法:逐位比较,i<o1,o2的最大长度;
//如果长度不等,就用short[length-1]与long[i]继续比较,i++,直到比出大小,或者等到循环结束(一直相等的情况)。
    public static String PrintMinNumberTest2(int [] numbers){
        if (numbers==null||numbers.length==0){
            return "";
        }
        String[] str=new String[numbers.length];
        for (int i=0;i<numbers.length;i++){
            str[i]= String.valueOf(numbers[i]);
        }

        Arrays.sort(str, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                int len=Math.max(o1.length(),o2.length());
                int c1=0;
                int c2=0;
                for (int i = 0; i < len; i++) {
                    if (i<o1.length()){
                        c1=Integer.parseInt(String.valueOf(o1.charAt(i)));
                    }
                    if (i<o2.length()){
                        c2=Integer.parseInt(String.valueOf(o2.charAt(i)));
                    }
//                    c1<c2,返回负值,不需要交换顺序;只有返回1,才需要交换o1,o2的顺序
                    if (c1<c2){
                        return -1;
                    }
                    if (c1>c2){
                        return 1;
                    }
                }
                return 1;
            }
        });
        StringBuilder sb=new StringBuilder();
        for (int i=0;i<str.length;i++){
            sb.append(str[i]);
        }
        return sb.toString();
    }

法2: 书上的,也是最多人用的:字符串拼接再比较大小。

 //    比较的两个字符串前后拼接再比较大小:s1+s2.compare(s2+s1)
    public static String PrintMiNumberTest(int [] numbers){
        if (numbers==null||numbers.length==0){
            return null;
        }
        String[] str=new String[numbers.length];
        for (int i = 0; i < numbers.length; i++) {
            str[i]= String.valueOf(numbers[i]);
        }
        Arrays.sort(str, (o1, o2) -> {
            String c1=o1+o2;
            String c2=o2+o1;
            return c1.compareTo(c2);
        });
        StringBuilder sb=new StringBuilder();
        for (int i=0;i<str.length;i++){
            sb.append(str[i]);
        }
        return sb.toString();
    }

法3: 

// 其他方法:lambda
    public static String PrintMinNumberTest1(int[] numbers) {
        List<String> list = Arrays.stream(numbers).mapToObj((num) -> String.valueOf(num)).collect(Collectors.toList());
        Collections.sort(list, (a, b) -> (a + b).compareTo(b + a));
        return list.stream().reduce((a, b) -> a + b).orElse("");
    }

 

全部评论

相关推荐

ArisRobert:统一解释一下,第4点的意思是,公司按需通知员工,没被通知到的员工是没法去上班的,所以只要没被通知到,就自动离职。就是一种比较抽象的裁员。
点赞 评论 收藏
分享
吃不饱的肱二头肌很想退休:tnnd 我以为选妹子呢,亏我兴高采烈的冲进来😠
投递快手等公司10个岗位
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务