-1

Here is the code

class Solution {
    public String[] reorderLogFiles(String[] logs) {
        Arrays.sort(logs, (s1, s2) -> {
            String[] split1 = s1.split(" ", 2);
            String[] split2 = s2.split(" ", 2);

            boolean isDigit1 = Character.isDigit(split1[1].charAt(0));
            boolean isDigit2 = Character.isDigit(split2[1].charAt(0));

            if(!isDigit1 && !isDigit2) {
                // both letter-logs. 
                int comp = split1[1].compareTo(split2[1]);
                if (comp == 0) return split1[0].compareTo(split2[0]);
                else return comp;
            } else if (isDigit1 && isDigit2) {
                // both digit-logs. So keep them in original order
                return 0; 
            } else if (isDigit1 && !isDigit2) {
                // first is digit, second is letter. bring letter to forward.
                return 1;
            } else {
                //first is letter, second is digit. keep them in this order.
                return -1; 
            }
        });
        return logs;
    }
}

This is the problem statement

You have an array of logs. Each log is a space delimited string of words.

For each log, the first word in each log is an alphanumeric identifier. Then, either:

Each word after the identifier will consist only of lowercase letters, or;
Each word after the identifier will consist only of digits.

We will call these two varieties of logs letter-logs and digit-logs. It is guaranteed that each log has at least one word after its identifier.

Reorder the logs so that all of the letter-logs come before any digit-log. The letter-logs are ordered lexicographically ignoring identifier, with the identifier used in case of ties. The digit-logs should be put in their original order.

Return the final order of the logs.

Example 1:

Input: logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"]
Output: ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"]

My Query

What I don't understand is, the difference between returning 0 and returning -1

What I thought was -1 doesn't change the original order of two objects when compared, but returning 0 does the same thing. So, what's the actual difference? Thank you

Miss Chanandler Bong
  • 4,081
  • 10
  • 26
  • 36
MrRobot9
  • 2,402
  • 4
  • 31
  • 68
  • 0 means the ordering is equal, -1 means the first argument comes before the second argument – Michael Mar 23 '20 at 18:36
  • but isn't the first argument already before the second argument? – MrRobot9 Mar 23 '20 at 18:37
  • zero doesn't necessarily "keep them in original order" btw. That depends entirely on the [stability of the sort](https://stackoverflow.com/questions/1517793/what-is-stability-in-sorting-algorithms-and-why-is-it-important). You got lucky, the underlying algorithm is - I believe - timsort, which is stable. Technically that is an implementation detail which could change in future versions. – Michael Mar 23 '20 at 18:41
  • Don't know what you mean. Like I said, there is a difference between 0 and -1, between something being equal and something being less than. "*-1 doesn't change the original order of two objects when compared*" It does. It puts the first argument before the second. – Michael Mar 23 '20 at 18:43

2 Answers2

0

While Comparable<T>'s int compareTo(T o) method compares this with the object specified, Comparator<T>'s int compare(T o1, T o2) compares two different instances of the same type. Both methods have a the same mathematical contract. As mentioned in Effective Java by Joshua Bloch:

Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. Throws ClassCastException if the specified object’s type prevents it from being compared to this object.

In the following description, the notation sgn(expression) designates the mathematical signum function, which is defined to return -1, 0, or 1, according to whether the value of expression is negative, zero, or positive.

• The implementor must ensure that sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception if and only if y.compareTo(x) throws an exception.)

• The implementor must also ensure that the relation is transitive: (x.compareTo(y) > 0 && y.compareTo(z) > 0) implies x.compareTo(z) > 0.

• Finally, the implementor must ensure that x.compareTo(y) == 0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.

• It is strongly recommended, but not required, that (x.compareTo(y) == 0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact.

Miss Chanandler Bong
  • 4,081
  • 10
  • 26
  • 36
0

For Comparator's, Comparable, etc..., there are two arguments passed. You return any negative number if the second argument is bigger, 0 if they are equal, and a positive number if the first argument is bigger. It doesn't have to be -1 or 1 for negative and positive numbers. For example, if you're comparing which number is larger, compare(5, 10) would return something negative, like -1, because 10 is larger than 5.