2022 KAKAO BLIND RECRUITMENT > 신고 결과 받기
def solution1(id_list, report, k):
answer = []
user_of_reported = {}
user_of_reporter = {}
for user in id_list:
user_of_reported[user] = set()
user_of_reporter[user] = set()
for r in report:
reporter, reported = r.split()
user_of_reported[reported].add(reporter)
user_of_reporter[reporter].add(reported)
for user in id_list:
res = 0
for reported in user_of_reporter[user]:
if len(user_of_reported[reported]) >= k: res += 1
answer.append(res)
return answer
user_of_reported
: 신고된 유저에 대해 신고자 리스트를 저장user_of_reporter
: 신고자에 대해 신고 대상 유저를 저장set을 통해 중복을 제거하고, 신고 목록을 통해 각 유저에 대해 신고된, 신고한 목록을 저장했다.
이를 통해 신고자에 대해 신고 대상 유저의 신고 회수가 k
회 이상이라면, 메일 회수를 증가시켜 저장시키는 방식으로 구현했다.
문제 통과에는 이상이 없었으나... 이게 맞는 풀이일까? 라는 의문이 들었다.
두개의 딕셔너리를 사용하지 않고도 구현할 방법이 있을텐데 비효율적인 것 같아 코드를 수정해 보았다.
def solution2(id_list, report, k):
answer = []
user_of_reported = {}
for user in id_list:
user_of_reported[user] = set()
for r in report:
reporter, reported = r.split()
user_of_reported[reported].add(reporter)
for user in id_list:
res = 0
my_reports = dict(filter(lambda x: user in x[1], user_of_reported.items()))
for reported in my_reports:
if len(user_of_reported[reported]) >= k: res += 1
answer.append(res)
return answer
두번째 풀이에서는 아까와 동일하지만, 신고자에 대한 딕셔너리를 filter 문법을 통해 구하였다.
filter(function, iterator)
파이썬 내장함수인 filter는 iterable한 객체에 대해 function을 만족하는 값만 모아 걸러주는 함수이다.
이때 반환값이 filter 객체이므로 list등으로 감싸 사용하면 된다.
이만하면 되었겠지... 생각을 하고 다른 사람의 풀이를 보았는데,, 훨씬 깔끔한 방법이 있었다.
def solution(id_list, report, k):
answer = [0] * len(id_list)
reports = {x : 0 for x in id_list}
for r in set(report):
reports[r.split()[1]] += 1
for r in set(report):
if reports[r.split()[1]] >= k:
answer[id_list.index(r.split()[0])] += 1
return answer
report 리스트의 요소는 "신고한사람 신고당한사람" 형식으로 이루어져 있는데, 각 유저마다 한 유저에게 신고하는 횟수는 아무리 신고를 했더라도 1회로 카운팅되기 때문에, 중복제거가 필요하다.
나는 이를 딕셔너리의 value를 set으로 관리했는데, 애초에 report리스트를 set을 통해 중복을 제거하고 시작할 수 있었다!
또한 report 요소에서 신고당한 유저가 k
회 이상 신고당했을 경우, answer에서 신고자에 해당하는 인덱스의 값을 더하는 식으로 시간복잡도를 감소시킬 수 있었다.