알고리즘/프로그래머스

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

정석이 2022. 3. 17. 20:35

 

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

 

코딩테스트 연습 - 신고 결과 받기

문제 설명 신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다. 각 유저는 한 번에 한 명의

programmers.co.kr

 

 

 

문제

 

 

 


 

 

진짜 대박....

 

 

다 통과하기 개어렵다.

 

 

 

 

내가 푼 방법(틀림)

 

def solution(id_list, report, k):
    report_num = [0] * len(id_list)
    stop_nik = []
    answer = [0] * len(id_list)
    for i in range(len(report)):
        report[i] = report[i].split()

    report = list(set(map(tuple,report)))

    for i in range(len(report)):
            for j in range(len(id_list)):
                if report[i][1] == id_list[j]:
                    report_num[j] += 1
                    break
    for i in range(len(report_num)):
            if report_num[i] >= 2:
                stop_nik.append(id_list[i])


    for i in range(len(report)):
        for j in range(len(stop_nik)):
            if report[i][1] == stop_nik[j]:
                answer[id_list.index(report[i][0])] += 1
            
    return answer

 

 

 

이건데 정말 노다가로 풀었다. 물론 틀렸음

 

 

 

어어 2개 맞았어 어어

 

 

도대체가....;;

 

 

 

 

 

그래서 남의 풀이 보고 완벽하게 이해했다.

 

 

 

 

 

남의 풀이 1 (틀림ㅋㅋ)

 

def solution(id_list, report, k):
    answer = [0] * len(id_list)
    report_num = {id : [] for id in id_list}
    stop = []
    
    for i in set(report):
        report = i.split()
        stop.append(report[1]) # 신고당한 애들 이름 넣어놓음
        report_num[report[0]].append(report[1])
        # report를 딕셔너리로 정리하는거임.
        # key = id_list, value = 신고한애들
        
    stop = set([i for i in stop if stop.count(i) >= k])
    # 1. i는 stop안에 있는 원소
    # 2. list.count(원소) 로 몇개 들었는지 확인. k 이상이면 i 넣음
    # 3. set을 이용해 중복제거해줌
    
    for key, value in report_num.items():
        for s in stop:
            if s in value:
                answer[id_list.index(key)] += 1
                # key값이 있는 index 위치의 answer 위치에 + 1
    
            
    return answer

 

 

아 좋네~ 하고 돌렸는데

 

 

 

 

응 시간초과야..

 

 

 

시간 초과!!

 

 

set을 돌릴때마다 해줘야해서 그런가? 해서 report = set(report) 하고 해봤는데에도 시간 초과!

 

 

 

13번째줄 때문인 것 같기도 하고... (시간 복잡도 공부좀 해야지.. 안그래도 수업 듣기로 했다.)

 

 

 

 

 

다시 남의껄 찾아 헤매....

 

 

 

남의 코드 2 

 

from collections import defaultdict

def solution(id_list, report, k):
    answer = [0] * len(id_list)
    
    report = set(report)  # 중복제거

    user_list_who_i_report = defaultdict(set) # 신고한애 : 신고당한애
    num_of_reported = defaultdict(int) # 신고당한 : 신고당한 횟수
    suspended = [] # 강퇴당할 유저목록

    for r in report:
        do_report, be_reported = r.split()

        num_of_reported[be_reported] += 1 # 신고당한 : 신고당한 횟수
        user_list_who_i_report[do_report].add(be_reported)
        # 신고한애 : 신고당한애

        # k번 당했으면 suspended에 넣어
        if num_of_reported[be_reported] == k:
            suspended.append(be_reported)
    for s in suspended:
        for i in range(len(id_list)):
            if s in user_list_who_i_report[id_list[i]]:
                # dict에서 dict[key] 하면 value를 출력함.
                # key = id_list일 때 정지먹을넘이 value에 있는지 확인
                # i는 id_list 에서의 index 역할을 하므로
                answer[i] += 1

    return answer

 

 

 

defaultdict라는게 있구나~~ 좋네..

 

 

 

https://velog.io/@syhan28/2022-KAKAO-%EA%B3%B5%EC%B1%84-%EC%8B%A0%EA%B3%A0-%EA%B2%B0%EA%B3%BC-%EB%B0%9B%EA%B8%B0%ED%8C%8C%EC%9D%B4%EC%8D%AC

 

 

여기 블로그에서 본 코드이다.

 

 

 

defaultdict를 사용하면 value 타입만 선언하고 사용할 수 있다.

 

 

 

 

 

 

맞아요 겨우했어요... 이해만 해도 한세월.......~

 

 

 


 

프로그래머스에 있는 다른 사람 풀이

 

 

 

 

 

 

 

음! 코드가 굉장히 짧네^^

 

 

report = {x : 0 for x in id_list} 하면 x인 key는 id_list 안에 있는 값이 되고 value는 0으로 통일된다.

 

 

set() 사용해서 중복제거 한 report 값 r 중에서 split() 으로 띄어쓰기로 조졌잖음?

 

 

예를 들어 neo frodo 이렇게 있으면 r[0] = neo, r[1] = frodo 일케 조져짐

 

 

여기서 [1] 값만 사용해서 reports dict()의 key값에 신고당한놈이 있으면 +1 해준것이다.

 

 

그 밑에 for문을 보면 reports{} 에서 value 값이 k 이상이면

 

 

id_list 값 중에 신고한 인간이 있는 index와 같은 answer index + 1 해준다. 이건 다들 알겠지..

 

 

직관적인데 엄청난 코드...!! 대단하다.....^^

 

 

 

 

다들 이런식으로 dictionary를 사용해서 풀었다.

 

 

남의풀이 2처럼 defaultdict를 굳이 사용하지 않아도 되지만 알아는 둬야지....!

 

 

 

오늘 알게된거 : dict() 만들 때 report = {x : 0 for x in id_list} 이거 사용하는거!! 랑

 

 

list.index() 사용하면 값이 들은 인덱스 알 수 있다는거!

 

 

 

화이팅!~~^^