[프로그래머스] 신고 결과 받기

MINJJ·2022년 7월 22일
0

프로그래머스

목록 보기
1/1
post-thumbnail

📝 문제

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

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에서 신고자에 해당하는 인덱스의 값을 더하는 식으로 시간복잡도를 감소시킬 수 있었다.

profile
Kookmin Univ. CS

0개의 댓글