[Leetcode/Medium] 로그 파일 재정렬 (937. Reorder Log Files, Swift)

2024. 6. 29. 13:40Algorithm

728x90

https://leetcode.com/problems/reorder-data-in-log-files/description/

 

🤔 문제 설명

각 로그는 공백으로 구분된 단어 문자열이며, 여기서 첫 번째 단어는 식별자입니다.
로그에는 문자 로그(식별자를 제외한 모든 단어는 소문자로 구성), 숫자 로그(식별자를 제외한 모든 단어는 숫자로 구성) 두 가지 유형이 있습니다.

제공되는 로그 배열을 아래 규칙에 맞추어 재정렬하세요.

  1. 문자로 구성된 로그는 모든 숫자 로그보다 앞에 와야 합니다.
  2. 식별자는 순서에 영향을 끼치지 않지만, 문자가 동일한 경우에는 식별자에 따라 사전순으로 정렬합니다.
  3. 단, 숫자 로그는 입력 순서대로 유지합니다.
logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"]
# ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"]

 

💡 풀이

규칙에 맞춰서 크게 두 단계로 나누어서 풀이를 가져갔다.

#1. "문자로 구성된 로그는 모든 숫자 로그보다 앞에 와야 합니다." -> 입력 Array를 확인하면서 문자 로그와 숫자 로그를 분리해서 Array에 담는다.
#2. "숫자 로그는 입력 순서대로 유지하며, 문자 로그는 정렬 + 동일한 경우에 식별자에 따라 정렬" -> 문자 로그 Array에 대해서만 첫 번째 인덱스를 제외하고 비교+정렬, 같은 경우에 이후에 첫 번째 인덱스 문자를 가지고 정렬 수행한다.

#1.
문자 로그와 숫자 로그를 구분하는 것은 Array를 반복하면서 식별자를 제외한 첫 번째 문자열의 문자만을 가지고 비교했다.
isLetter 메서드를 이용해 문자인 경우 letterLogs Array에, 아닌 경우 digitLogs Array에 append해줬다.
*문자열의 첫 번째 문자를 꺼내는 first는 옵셔널로 꺼내지기 때문에 guard-let으로 옵셔널 바인딩 과정을 거쳐줘야만 했다.

#2.
이후 문자 로그 Array만을 대상으로 정렬을 해주었다.
sort 클로저 안에 규칙을 커스텀할 수 있었고, [1...] 이후에 문자를 joined로 묶어서 비교하고 만약 같은 경우에는 식별자로 비교할 수 있도록 규칙을 설정했다.

마지막에는 정렬된 문자 로그와 저장해둔 숫자 로그를 합해서 최종 반환 시켜줬다.

 

🧑🏻‍💻 코드 (Swift ver.)

class Solution {
    func reorderLogFiles(_ logs: [String]) -> [String] {
        var letterLogs = [String]()
        var digitLogs = [String]()

        // letterLog와 digitLog 분리해서 Array에 담기
        for log in logs {
            guard let check = log.split(separator: " ")[1].first as? Character else { continue }
            check.isLetter ? letterLogs.append(log) : digitLogs.append(log)
        }

        // letterLog 정렬하기
        letterLogs.sort { log1, log2 in
            let log1Split = log1.split(separator: " ")
            let log2Split = log2.split(separator: " ")
            let log1NoId = log1Split[1...].joined(separator: " ")
            let log2NoId = log2Split[1...].joined(separator: " ")
            return log1NoId==log2NoId ? log1Split[0]<log2Split[0] : log1NoId < log2NoId
        }

        // 문자 로그와 정수 로그 합치기
        return letterLogs+digitLogs
    }
}
728x90