https://school.programmers.co.kr/learn/courses/30/lessons/92334
이번 문제는 각 유저별로 처리 결과 메일을 받은 횟수를 배열에 담아 return 하는 문제입니다!
여기서 제공한 문제의 조건을 보면 문제를 유추 할 수 있는 힌트가 숨겨져 있는거 같은데
한 유저를 여러 번 신고할 수도 있지만
라는 문장에서 Dictinary 로 풀어야겠다 라는 생각을 했고
동일한 유저에 대한 신고 횟수는 1회로 처리됩니다.
라는 의미는 Set 을 사용하면 되겠다 라는 생각을 했습니다!
유저별로 처리 결과 메일을 받은 횟수를 카운팅 해야하니 배열 하나가 더 필요하겠다고 생각도 했구요!
func solution(_ id_list:[String], _ report:[String], _ k:Int) -> [Int] {
var result = Array(repeating: 0, count: id_list.count)
var reportData = [String: Set<String>]()
for data in report {
let splitData = data.split(separator: " ").map{ String($0) }
reportData[splitData[1], default: Set()].insert(splitData[0])
}
for value in reportData.values {
if value.count >= k {
for person in value {
result[id_list.firstIndex(of: person)!] += 1
}
}
}
return result
}
result
처리 결과 메일의 수를 담고 있는 배열이고 reportData
는 신고 당한 유저를 Key
로, 신고한 유저를 Value
로 만든 딕셔너리 입니다!
동일한 유저에 대해 신고 횟수는 1회로 처리를 해야하니까 Value 의 유형은 Set<String>
으로 미리 중복을 예방해주었습니다!
report
배열에 있는 데이터를 통해서 분류를 for
안에서 해주고 해당 유저가 신고한 유저의 신고 수가 k
이상일 경우를 찾아야 하고 똑같은 index
에 값을 넣어야 하기 때문에 이중 for
문을 사용해서 문제를 해결했습니다!
문제를 보고 쉽겠다 라고 생각했지만.. 딕셔너리 사용에서.. 에러가 발생했기도 하고 풀다 보니 헷깔리는 부분도 많았습니다..
func solution(_ id_list:[String], _ report:[String], _ k:Int) -> [Int] {
var reported: [String: Int] = [:]
var user: [String: [String]] = [:]
for r in Set(report) {
let splited = r.split(separator: " ").map { String($0) }
user[splited[0]] = (user[splited[0]] ?? []) + [splited[1]]
reported[splited[1]] = (reported[splited[1]] ?? 0) + 1
}
return id_list.map { id in
return (user[id] ?? []).reduce(0) {
$0 + ((reported[$1] ?? 0) >= k ? 1 : 0)
}
}
}
처음에 딱 보고.. 한참 동안 생각을 했습니다..
어떻게 하면 저렇게 바로 풀까 하구요..
reported
딕셔너리는 신고당한 사람을 key
로, 신고 수를 value
로 설정했고 user
딕셔너리는 신고한 사람을 key
, 신고 당한 사람을 value
로 사용했습니다.
저는 딕셔너리의 value 유형을 Set<String>
으로 해서 중복을 예방하려고 했지만 이분은 report
매개변수 자체를 Set
으로 바꿔서 중복을 없애고 반복할 데이터의 수 자체를 줄여버렸습니다......
for r in Set(report)
이 코드는 정말 문제에서 신의 한 수 인거 같습니다....
그리고 저는 이중 for 문으로 id_list
를 처음부터 끝까지 반복하지만 위의 풀이는 딱 한번만 탐색하면서 각 사용자의 신고횟수도 한번만 조회하게 됩니다...
저의 풀이의 걸린시간만 봐도 테스트 3,9,14,20,21 에서 큰 차이가 났고 거의.. 10배 이상의 차이가 난 부분도 있었습니다
report 가 쵀대 200,000 개이니 당연하게 차이가 크게 벌어질 수 밖에 없는거 같네요
저의 코드가 더.. 직관적이고 이해하기 쉽겠지만...
고차함수를 이해하는데 좀 시간이 걸리겠지만...
훨씬 더 효율적인 코드인거는 틀림이 없네요...
한번에 코드를 적기에는 힘들겠지만 계속 코테 공부하면서 노력해야겠습니다!