剑指 Offer 45. 把数组排成最小的数-贪心+排序

1.题目

2.思路

思路:一开始没有任何思路,因为不知道怎么才能保证两个数那个数更小放前面,所以完全不会做....

之后看了一样答案的思路,太妙了啊!!!

正解:两个数,谁应该放前面?? --贪心,每次都把两个数拼接在一起,如果x + y 拼接的数 大于 y + x 拼接的数,那么x就应该放在y的前面。那么继续比较下一个数,不断后移动,所以就类似冒泡排序了。-- n * n   --34ms

class Solution {
    public String minNumber(int[] nums) {
        int n = nums.length;
        if(n == 0) return "";
        StringBuffer sb = new StringBuffer();
        for(int i = 0 ; i < n ; i++){
            for(int j = i + 1; j < n ; j++){
                if(isBig(nums[i], nums[j])){
                    int t = nums[i];
                    nums[i] = nums[j];
                    nums[j] = t;
                }
            }
            // System.out.println(nums[i]);
            sb.append(nums[i]);
        }
        return sb.toString();
    }

    public boolean isBig(int i, int j){
        String s1 = i + ""+ j +"";
        double d1 = Double.parseDouble(s1);
        String s2 = j + ""+ i +"";
        double d2 = Double.parseDouble(s2);
        // System.out.println(d1 +">>>" + d2);
        return d1 > d2;
    }
}

改进1 -贪心策略不变,排序可以用快排啊,这样就nlogn  --时间是44ms,居然还变多了,神奇。

可能是快排模板写得不太对???

class Solution {
    public String minNumber(int[] nums) {
        int n = nums.length;
        if(n == 0) return "";
        // int[]arr = new int[]{0,2,3,1,4,6,-2,7};
        quickSort(0, nums.length - 1, nums);
        StringBuffer sb = new StringBuffer();
        for(int i : nums)
            sb.append(i);

        // StringBuffer sb = new StringBuffer();
        // for(int i = 0 ; i < n ; i++){
        //     for(int j = i + 1; j < n ; j++){
        //         if(isBig(nums[i], nums[j])){
        //             int t = nums[i];
        //             nums[i] = nums[j];
        //             nums[j] = t;
        //         }
        //     }
        //     // System.out.println(nums[i]);
        //     sb.append(nums[i]);
        // }
        return sb.toString();
        // return "";
    }
    public void quickSort(int low, int high, int[]arr){
        int start = low, end = high;
        int key = arr[low];
        while(start < end){
            while(start < end && isBig(arr[end], arr[low]))end--;
            while(start < end && isBig2(arr[low], arr[start]))start++;
            if(start == end)break;
            // 交换大于和小于的位置,便于继续循环
            swap(start, end, arr);
        }
        // 第一次循环结束,交换start 和 最开始的起始位置low的值。
        swap(low, start, arr);
        // 如果其实位置low < start ,说明还要继续快排。
        if(low < start)
            quickSort(low, start - 1, arr);
        if(high > end)
            quickSort(end + 1, high, arr);
    }
    public void swap(int i, int j, int[]arr){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    // i > j , return true
    public boolean isBig(int i, int j){
        String s1 = i + ""+ j +"";
        double d1 = Double.parseDouble(s1);
        String s2 = j + ""+ i +"";
        double d2 = Double.parseDouble(s2);
        // System.out.println(d1 +">>>" + d2);
        return d1 >= d2;
    }

     public boolean isBig2(int i, int j){
        String s1 = i + ""+ j +"";
        double d1 = Double.parseDouble(s1);
        String s2 = j + ""+ i +"";
        double d2 = Double.parseDouble(s2);
        // System.out.println(d1 +">>>" + d2);
        return d1 > d2;
    }
}

改进2 -贪心策略不变,排序可以用快排, 然后比较两个数,直接用内置的sort函数(),并且用String数组存储也可以减少时间。

class Solution {
    public String minNumber(int[] nums) {
        // 内置函数
        int n = nums.length;
        if(n == 0)return "";
        String[]str = new String[n];
        for(int i = 0 ; i <  n ; i++)
            str[i] = String.valueOf(nums[i]);
        // 内置函数版本
        // Arrays.sort(str, (a, b)->(a + b).compareTo(b + a));

        // 自己写
        Arrays.sort(str, (a, b)->{
            if(Double.parseDouble(a + b) >= Double.parseDouble(b + a))return 1;
            else return -1;
        });

        StringBuffer sb = new StringBuffer();
        for(String i : str)
            sb.append(i);

        return sb.toString();
    }
}

3.结果

 4.总结

1.如何比较两个数交换后的拼接大小?

可以用Double.parseDouble(i +""+j);

也可以用内置比较字符串大小函数,(a + b).compareTo(b + a);//大概率想不起来

2.自定义排序?

Arrays.sort(nums, (a, b)->{
    if(a > b) return 1;
    else return -1;
});

3.学会StringBuffer sb = new StringBuffer() (线程安全)

sb.append(str[i]);

sb.toString();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值