class Solution:
def reorderLogFiles(self, logs):
letter_logs = []
digit_logs = []
for log in logs:
id_, rest = log.split(" ", 1)
if rest[0].isdigit():
digit_logs.append(log)
else:
letter_logs.append((rest, id_, log))
# Sort by content, then identifier
letter_logs.sort(key=lambda x: (x[0], x[1]))
return [log[2] for log in letter_logs] + digit_logs
class Solution {
public:
vector<string> reorderLogFiles(vector<string>& logs) {
vector<pair<string, string>> letter_logs;
vector<string> digit_logs;
for (const string& log : logs) {
int pos = log.find(' ');
string id = log.substr(0, pos);
string rest = log.substr(pos + 1);
if (isdigit(rest[0])) {
digit_logs.push_back(log);
} else {
letter_logs.emplace_back(rest, id);
}
}
sort(letter_logs.begin(), letter_logs.end(), [](const pair<string, string>& a, const pair<string, string>& b) {
if (a.first == b.first)
return a.second < b.second;
return a.first < b.first;
});
vector<string> result;
for (const auto& p : letter_logs) {
result.push_back(p.second + " " + p.first);
}
result.insert(result.end(), digit_logs.begin(), digit_logs.end());
return result;
}
};
class Solution {
public String[] reorderLogFiles(String[] logs) {
List<String> letterLogs = new ArrayList<>();
List<String> digitLogs = new ArrayList<>();
for (String log : logs) {
int idx = log.indexOf(' ');
if (Character.isDigit(log.charAt(idx + 1))) {
digitLogs.add(log);
} else {
letterLogs.add(log);
}
}
Collections.sort(letterLogs, (a, b) -> {
int idxA = a.indexOf(' ');
int idxB = b.indexOf(' ');
String contentA = a.substring(idxA + 1);
String contentB = b.substring(idxB + 1);
if (contentA.equals(contentB)) {
return a.substring(0, idxA).compareTo(b.substring(0, idxB));
}
return contentA.compareTo(contentB);
});
String[] result = new String[logs.length];
int i = 0;
for (String log : letterLogs) result[i++] = log;
for (String log : digitLogs) result[i++] = log;
return result;
}
}
var reorderLogFiles = function(logs) {
const letterLogs = [];
const digitLogs = [];
for (const log of logs) {
const idx = log.indexOf(' ');
const id = log.substring(0, idx);
const rest = log.substring(idx + 1);
if (/\d/.test(rest[0])) {
digitLogs.push(log);
} else {
letterLogs.push([rest, id, log]);
}
}
letterLogs.sort((a, b) => {
if (a[0] === b[0]) {
return a[1] < b[1] ? -1 : 1;
}
return a[0] < b[0] ? -1 : 1;
});
return letterLogs.map(x => x[2]).concat(digitLogs);
};
You are given an array of log strings, logs
. Each log is a space-delimited string with two parts:
To solve this problem, we need to distinguish between two types of logs: letter-logs and digit-logs. The main challenge is to sort the letter-logs according to their content and identifier, while keeping the digit-logs in their original order. A brute-force approach might try to sort all logs together, but this would not respect the special ordering rules for digit-logs. Instead, it's better to separate the logs into two groups, process each group as required, and then combine them.
The key insight is to treat letter-logs and digit-logs differently:
Let's break down the solution step by step:
We use a list or array to store each group. Sorting is efficient because we only sort letter-logs, and digit-logs are simply appended.
Let's use the following example input:
logs = [ "dig1 8 1 5 1", "let1 art can", "dig2 3 6", "let2 own kit dig", "let3 art zero" ]
After sorting by content, we get:
This ordering meets all problem requirements.
The key to solving "Reorder Data in Log Files" is to separate the problem into manageable parts: identify letter-logs and digit-logs, sort only the letter-logs with a custom comparator, and maintain the original order of digit-logs. This approach leverages efficient sorting and simple list manipulations, resulting in a clean and effective solution. The elegance comes from reducing the problem to sorting with a custom key and combining the results in a straightforward way.