LeetCode-179:数组自动排序工具Arrays.sort(),比较器Comparator的正确打开方式

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_41885819/article/details/100553674

题目描述:给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数
实例一:输入: [10,2] 输出: 210
实例二:输入: [3,30,34,5,9] 输出: 9534330

在这道题上花费的时间比较多,主要是考虑问题的总是不够全面,提交了很多次都没有通过。
一开始的思路是,让每两个数进行比较,当然肯定不是直接比较,比如说5和21比较,后者大,但是需要将5排在前面。所以很容易想到比较第一位。那么如果第一位相同,第二位不同;前两位相同第三位不同呢,等等等等。所以我想到的是先将两个数字补充为同样位数的再进行比较。比如5和21,我先将5换成50,再与21进行比较。很快,一顿操作猛如虎,完成了测试代码,提交后发现并没有通过。测试代码为[12,121],按照我的逻辑,进行比较的数为120和121,由于121大,所以将121放在前面,组合出来的数为12112,显然,这个数肯定比12121小。瞬间有种被KO的感觉。
接着,调整一下思路,干脆直接将两个数直接拼接了再进行比较,比如A和B进行比较,先拼接成AB和BA,再将AB和BA进行大小比较。由于数字溢出最大值,所以肯定是将拼接后的字符串转换成char数组,然后再用每位上的char进行大小比较。
实例代码如下:

/**
 * 给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。
 */
public class LeeCode179 {
    public String largestNumber(int[] nums) {
        String largestNumberString = "";
        for (int i = 0, len = nums.length; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) {
                if (numComp(nums[i], nums[j])) {
                    int temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                }
            }
        }
        //防止[0,0]
        if(nums[0]==0){
            return "0";
        }
        for (int num : nums) {
            largestNumberString = largestNumberString + num + "";
        }
        return largestNumberString;
    }

    /**
     * 将两个数字补齐为同样位数后再比较大小
     * @param num1
     * @param num2
     * @return
     */
    private boolean numComp(int num1, int num2) {
        boolean changeOrNot = false;
        //当需要调换两个元素顺序时,返回true
        String str1 = Integer.toString(num1)+Integer.toString(num2);
        String str2 = Integer.toString(num2)+Integer.toString(num1);
        char[] chars1 = str1.toCharArray();
        char[] chars2 = str2.toCharArray();
        //比较两个数组对应位大小
        for(int i=0,len=str1.length();i<len;i++){
            if(chars1[i]<chars2[i]){
                return true;
            }else if(chars1[i]>chars2[i]){
                return false;
            }
        }
        return changeOrNot;
    }

}

建议根据思路再手动编辑代码,因为自己也在调试过程中遇到了很多考虑不全面,或者思维局限的地方。比如针对测试数据[0,0],如果在按照之前的逻辑操作下来,返回的字符串结果就是 00 ,不符合要求,于是在输出前可以加上一个对首位的判断。

到了这里,本该漏出一丝惬意的笑容,可惜,执行时间和消耗内存方面双双没有什么优势,于是瞻仰了一下官方的示例代码。官方的思路更加简单清晰一些,先是将int类型的数组一次性转换为String类型的数组,然后使用自定义的数组排序工具进行自动排序,然后再按顺序将排序后的String通过字符串拼接,打印出结果。这种方法确实高效很多,特别是数据更大的时候。同时,排序之前的一些预处理,或者说是特殊情况特殊处理,也能有效减少一些无必要流程的执行判断。
官方实例代码如下:

public class LeeCode179Standard {
    public String largestNumber(int[] num) {
        if (num.length == 0) {
            return "";
        }
        if (num.length == 1) {
            return Integer.toString(num[0]);
        }
        String[] str = new String[num.length];
        for (int i = 0; i < num.length; i++) {
            str[i] = Integer.toString(num[i]);
        }
        Arrays.sort(str, new StringComparator());
        StringBuilder sb = new StringBuilder("");
        for (int i = num.length - 1; i >= 0; i--) {
            sb.append(str[i]);
        }
        if (sb.charAt(0) == '0') {
            return "0";
        }
        return sb.toString();
    }
    class StringComparator implements Comparator<String> {
        public int compare(String s1, String s2) {
            if (s1.length() == 0 && s2.length() == 0) {
                return 0;
            }
            if (s2.length() == 0) {
                return 1;
            }
            if (s1.length() == 0) {
                return -1;
            }
            for (int i = 0; i < s1.length() && i < s2.length(); i++) {
                if (s1.charAt(i) > s2.charAt(i)) {
                    return 1;
                } else if (s1.charAt(i) < s2.charAt(i)) {
                    return -1;
                }
            }
            if (s1.length() == s2.length()) {
                return 0;
            }
            if (s1.length() > s2.length()) {
                if (s1.charAt(0) < s1.charAt(s2.length())) {
                    return 1;
                } else if (s1.charAt(0) > s1.charAt(s2.length())) {
                    return -1;
                } else {
                    return compare(s1.substring(s2.length()), s2);
                }
            } else {
                if (s2.charAt(0) < s2.charAt(s1.length())) {
                    return -1;
                } else if (s2.charAt(0) > s2.charAt(s1.length())) {
                    return 1;
                } else {
                    return compare(s1, s2.substring(s1.length()));
                }
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41885819/article/details/100553674