func solution(_ m:String, _ musicinfos:[String]) -> String {
let m = convert(m)
var result = ("(None)", 0) //곡 제목, 재생 시간
for info in musicinfos {
let data = info.split(separator: ",").map{ String($0) }
let playtime = time(data[1]) - time(data[0])
if isContain(convert(data[3]), playtime) && result.1 < playtime {
result = (data[2], playtime)
}
}
return result.0
func convert(_ string: String) -> String {
return string
.replacingOccurrences(of: "C#", with: "c")
.replacingOccurrences(of: "D#", with: "d")
.replacingOccurrences(of: "F#", with: "f")
.replacingOccurrences(of: "G#", with: "g")
.replacingOccurrences(of: "A#", with: "a")
}
func time(_ t: String) -> Int {
let split = t.split(separator: ":").map{ Int($0)! }
return split[0]*60 + split[1]
}
func isContain(_ base: String, _ playtime: Int) -> Bool {
var play = String(repeating: base, count: playtime/base.count+1)
play = String(play.prefix(playtime))
return play.contains(m)
}
}
재생 시간만큼의 악보를 구하기 위해서는 아래와 같이 구현할 수 있다. 문제를 풀 때는 1번 방식이 시간 복잡도 측면에서 더 효율적이라고 생각했는데, 사실 최악의 경우엔 차이가 없다. 둘 다 1440개의 원소를 살펴야 한다.. 구현하기 쉬운건 무조건 2번.
1. Array 변환 후, 슬라이싱
1번 방식의 경우 base인 주어진 악보 정보의 길이가 짧을 경우, 2번보다 더 효율적일 것이다. 슬라이싱을 위해 탐색하는 데이터의 길이가 짧기 때문이다.
func isContain(_ base: String, _ playtime: Int) -> Bool {
var play = String(repeating: base, count: playtime/base.count)
let baseArray = Array(base).map{ String($0) }
play += baseArray[0..<playtime%base.count].joined()
return play.contains(m)
}
2. prefix 메서드 사용
base로 주어진 악보 정보의 길이가 길다면, 1번에 비해 비효율적이다. 하지만 최악의 경우를 고려하면 똑같다^^.
1번 방식보다 훨씬 간편한 2번.
func isContain(_ base: String, _ playtime: Int) -> Bool {
var play = String(repeating: base, count: playtime/base.count+1)
play = String(play.prefix(playtime))
return play.contains(m)
}
[프로그래머스] H-Index (0) | 2023.12.18 |
---|---|
[프로그래머스] n^2 배열 자르기 (1) | 2023.12.15 |
[프로그래머스] 괄호 회전하기 (0) | 2023.12.15 |
[프로그래머스] 짝지어 제거하기 (0) | 2023.12.12 |
[프로그래머스] 다음 큰 숫자 (1) | 2023.12.11 |