937. Reorder Data in Log Files

문제

You are given an array of logs. Each log is a space-delimited string of words, where the first word is the identifier.
There are two types of logs:\

  1. The letter-logs come before all digit-logs.\
  2. The letter-logs are sorted lexicographically by their contents. If their contents are the same, then sort them lexicographically by their identifiers.\
  3. The digit-logs maintain their relative ordering.\

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"]
Explanation:
The letter-log contents are all different, so their ordering is "art can", "art zero", "own kit dig".
The digit-logs have a relative order of "dig1 8 1 5 1", "dig2 3 6".

Example 2:

Input: logs = ["a1 9 2 3 1","g1 act car","zo4 4 7","ab1 off key dog","a8 act zoo"]
Output: ["g1 act car","a8 act zoo","ab1 off key dog","a1 9 2 3 1","zo4 4 7"]

해결

생각

System.out.printf("%d\n", "def".chars().reduce(0, Integer::sum)); // 303
System.out.printf("%d\n", "abcd".chars().reduce(0, Integer::sum)); // 394

코드

public String[] reorderLogFiles(String[] logs) {
    String[] answer = new String[logs.length];
    String[] digits = new String[logs.length];
    TreeMap<String, TreeMap<String, String>> letters = new TreeMap<>();
    int answerIdx = 0;
    int digitsIdx = 0;
    for (String log : logs) {
        int idxOfFirstSpace = log.indexOf(' ');
        String logDetail = log.substring(idxOfFirstSpace + 1);
        // 0 = 48, 9 = 57 | A = 65, Z = 90 | a = 97, z = 122
        if (48 <= logDetail.charAt(0) && logDetail.charAt(0) <= 57) {
            digits[digitsIdx++] = log;
        } else {
            // logDetail 간의 길이가 다르고, id가 뒤에 붙으면서 id가 순서에 영향을 주게 된다
            if (! letters.containsKey(logDetail)) {
                TreeMap<String, String> subLetters = new TreeMap<>();
                subLetters.put(log, log);
                letters.put(logDetail, subLetters);
                continue;
            }
            letters.get(logDetail).put(log, log);
        }
    }
    for (TreeMap<String, String> subLetters : letters.values()) {
        for (String subLetter : subLetters.values()) {
            answer[answerIdx++] = subLetter;
        }
    }
    for (int i = 0; i < digitsIdx; i++) {
        answer[answerIdx++] = digits[i];
    }

    return answer;
}

결과

Runtime: 2 ms, faster than 99.86% of Java online submissions for Reorder Data in Log Files.
Memory Usage: 39 MB, less than 93.37% of Java online submissions for Reorder Data in Log Files.

리트코드 다른 코드

public String[] reorderLogFiles(String[] logs) {
    int insert_pt = logs.length - 1; // where to put the next digit logs
    while (insert_pt >= 0 && Character.isDigit(logs[insert_pt].charAt(logs[insert_pt].length() - 1))) {
      --insert_pt;
    }
    for (int i = insert_pt; i >= 0; --i) {
        String str = logs[i];
        if (Character.isDigit(str.charAt(str.length() - 1))) {
            String temp = logs[insert_pt];
            logs[insert_pt] = logs[i];
            logs[i] = temp;
            --insert_pt;
        }
    }
    
    Arrays.sort(logs, 0, insert_pt + 1, (x,y)->{
        int start_x = 0;
        while (x.charAt(start_x++) != ' ');
        int start_y = 0;
        while (y.charAt(start_y++) != ' ');
        for (; start_x < x.length() && start_y < y.length(); ++start_x, ++start_y) {
            int comp = Character.compare(x.charAt(start_x), y.charAt(start_y));
            if (comp != 0) return comp;
        }
        
        if (start_x == x.length() && start_y == y.length()) {
            return x.compareTo(y);
        } else return start_x < x.length() ? 1 : -1;
    });
    
    return logs;
}