LeetCode-179: automatically sort an array of tools Arrays.sort (), the correct comparator Comparator Open

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/qq_41885819/article/details/100553674

Description Title: Given a set of non-negative integers, their order rearranged so as to form a largest integer
Example a: Input: [10,2] Output: 210
Example 2: Input: [3,30,34,5, 9] output: 9,534,330

More time spent on this question, mainly on account of a problem is always incomplete, submitted many times did not pass.
The idea from the beginning was, so that every two numbers are compared, of course, is certainly not a direct comparison, for example, 5 and 21, the latter large, but need to be standing in the front 5. So it is relatively easy to think first. So if the first bit the same, second place different; the same top two third place different then, and so much more. So my first thought was to add two numbers for the same number of bits and then compare. For example, 5 and 21, my first 5 into 50, and then compared with the 21. Soon, the meal operate fierce as a tiger, completed the test code, after submitting discovered and did not pass. Test code [12, 121], in accordance with my logic, for comparing the number of 120 and 121, due to the large 121, 121 will be placed in front of it, out of the combination number 12112, obviously, this number is certainly less than 12,121. A kind of feeling of being instantly KO's.
Next, adjust the idea, simply direct splicing of the two numbers then compared directly, such as A and B are compared, the first stitched AB and BA, AB and then compare the size BA. Since the maximum number overflow, so it must be converted into a string of splicing char array, then use on char each size comparison.
Example code:

/**
 * 给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。
 */
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;
    }

}

Recommendations based on the idea to manually edit the code, because they also encountered a lot of consideration is not comprehensive, or limitations of thinking of local debugging. For example, test data [0, 0], if the logical operation as previously down, the result is the returned string 00, does not meet the requirements, then the output may be added prior to a determination of the first place.

Here, and this trace the leak pleasant smile, but unfortunately, the execution time and memory consumption in both aspects of no advantage, so what official visited the sample code. The official thinking is more simple and clear some of the first array of type int time convert to an array of type String, then use a custom array sorting tool automatically sort, then press the order String sorted by string concatenation, print The results. This method is efficient and does a lot, especially when larger data. Meanwhile, some pre-processing prior to sorting, it is a special case or special treatment can be effectively performed to reduce the number of unnecessary determination process.
Examples of the official code is as follows:

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()));
                }
            }
        }
    }
}

Guess you like

Origin blog.csdn.net/qq_41885819/article/details/100553674