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

hyun·2022년 5월 16일
0

알고리즘 문제

목록 보기
7/10
post-thumbnail

https://programmers.co.kr/learn/courses/30/lessons/92334

문제 이해

유저는 다른 유저를 신고할 수 있고, k번 이상 신고당한 유저는 이용 정지를 당한다. 유저 A가 신고한 유저가 이용 정지를 받는다면 유저 A에게 신고 결과를 발송해야 한다. 신고 횟수에 제한은 없지만, 동일한 유저에 대해 여러번 신고를 하게 되면 1번으로 처리된다.

문제 접근

가장 먼저 딕셔너리를 사용해야겠다는 생각이 들었다. 신고현황을 알 수 있는 딕셔너리를
{신고한 유저 : {신고당한 유저1, 신고당한유저2}}의 형태로 구성하고, 유저별로 신고당한 횟수를 저장하면 좋겠다. 그리고 k번 이상 이용 정지를 당하게 되는 유저들의 정보를 담은 리스트가 필요하다.

즉, 세 가지의 자료가 필요하다.

  • 신고 현황(딕셔너리) {신고한 유저: {신고당한 유저 1, 신고당한 유저 2}}
  • 신고당한 횟수(리스트) [0,0,1,1]
  • 이용정지된 유저(리스트) ['neo', 'frodo']

그리고 한 유저에 대해 같은 유저가 여러 번 신고를 하는 경우 1회로 처리되므로, 전체 신고내역을 set으로 한번 감싸주어 중복을 제거해주면 좋겠다.

collections.defaultdict

어떤 키(key)에 대한 값(value)이 없는 경우에 대해서 처리할 때 편리한 모듈이다. 주어진 객체의 기본값을 딕셔너리의 초기값으로 설정할 수 있다. 말 그대로 처음 키를 지정할 때 값을 주지 않으면 해당 키에 대한 값을 기본값으로 설정해 준다.

from collections import defaultdict
int_dict = defaultdict(int) # 디폴트값이 0
list_dict = defaultdict(list) # 디폴트값이 빈 list
set_dict = defaultdict(set) # 디폴트값이 빈 set

값을 지정하지 않은 key1은 0, key2는 지정된 값이 출력되는 것을 확인할 수 있다.

사용 예

키의 개수를 세야 하는 상황에서 유용하다. 예를 들어 문자열에 있는 알파벳의 개수를 세야 하는 코드를 보자.

text = "sdagfdgasdgasd"
text_dict = defaultdict(int)
for t in text:
	text_dict[t] += 1
print(text_dict)

코드

# # https://programmers.co.kr/learn/courses/30/lessons/92334
from collections import defaultdict

def solution(id_list, report, k):
    answer = [0] * len(id_list)
    report = set(report)

    # 유저가 신고한 유저 목록
    report_list = defaultdict(set)

    # 유저가 신고당한 횟수
    reported_num = defaultdict(int)

    # 이용정지를 당한 유저 리스트
    banned = []

    for r in report:
        reporter, reportee = r.split()
        reported_num[reportee] += 1
        report_list[reporter].add(reportee)

        if reported_num[reportee] >= k:
            banned.append(reportee)

    for b in banned:
        for i in range(len(id_list)):
            if b in report_list[id_list[i]]:
                answer[i] += 1

    return answer
profile
프론트엔드를 공부하고 있습니다.

0개의 댓글