문제 보러 가기: https://programmers.co.kr/learn/courses/30/lessons/92334
코딩테스트 연습 - 신고 결과 받기
문제 설명 신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다. 각 유저는 한 번에 한 명의
programmers.co.kr
<나의 풀이>
function solution(id_list, report, k) {
var answer = Array.from({length: id_list.length}, ()=>0);
var report_map = new Map(); // 신고 명단
id_list.forEach((id)=>{
report_map.set(id, []); // 신고 명단 초기화(각 id마다 빈 배열을 할당)
})
var report_count = new Map(); // 피신고자 누적 횟수
var report_set = new Set(report);
report_set.forEach((re)=>{
var [reporter, reported] = re.split(" ");
// 신고 명단 작성
report_map.set(reporter, [...report_map.get(reporter), reported]);
// 피신고자 누적 횟수 계산
if(report_count.has(reported)) report_count.set(reported, report_count.get(reported) + 1);
else report_count.set(reported, 1);
})
const reported_list = Array.from(report_map.values());
report_count.forEach((value, key)=>{
if(value >= k) {
reported_list.forEach((list, index)=>{
if(list.includes(key)) answer[index] = answer[index] + 1;
})
}
})
return answer;
}
<해설>
이 문제를 풀기 위해서는 누가 누구를 신고했는지에 대한 "신고 명단"과, 누가 몇번 신고 당했는지에 대한 "피신고 누적 횟수"가 필요하다.
전자는 각 유저의 신고 명단에 최종 신고 처리된 사람들이 있다면 카운트해주기 위함이고, 후자는 각 유저별로 신고 당한 횟수가 k번을 넘었는지 알기 위함이다.
<사용 알고리즘>
Javascript Map, Set 자료형
Map, Set의 개념만 알고 있다면 두 개를 활용해서 충분히 풀 수 있는 문제다.
1. answer는 id_list의 갯수만큼 각 원소가 0으로 초기화된 배열로 만들어준다. (Array.from 이용)
구하고자 하는 값이 각 유저 별 최종 신고 완료 메일을 받은 횟수를 구하는 것이기 때문이다.
2. id_list의 순서대로 report_map을 빈 배열로 초기화 해준다.
이렇게 한 이유는 추후에 map의 value만을 가지고 최종 신고 처리된 사람들이 있다면 그 누적 값을 answer 배열에서 같은 index을 찾아서 바로 넣어주기 위함이다.
3. 피신고 누적 횟수를 구하기 위해 report_count을 Map 객체로 만든다.
4. report 배열로 신고 명단을 만드는데, 그 전에 ** 중복 신고 무효처리를 위해 Set을 이용, report 원본 배열에서 중복 제거를 해준다.
ex) "muzi prodo", "muzi prodo" 는 무지가 프로도를 2번이나 신고한 것이기 때문에 1번으로 친다.
5. 중복 제거된 report_set 배열을 forEach loop로 돌려서 신고명단을 작성함과 동시에, 피신고 횟수를 누적한다. (불필요한 for문의 반복을 피하기 위함)
6. 신고 명단(report_map)의 value만을 가져다가 id_list로 정렬된 신고 명단(reported_list) 배열을 구한다. (map.prototype.values 이용)
7. 누적 횟수 배열을 forEach loop을 돌려 k번 이상 신고된 유저가 있다면, reported_list에 해당 유저가 들어있는지 구한 후(array.prototype.includes 이용) 있다면 answer의 index번째 값에 1을 더한다.
<총평>
처음에 중복 제거하는 것을 깜빡하여 테스트 문제 2번을 틀렸었다. 중복 제거 로직만 잘 끼워넣으면 풀기에는 무난하다. Map, Set의 개념을 확실히 아는 것이 중요하다. 6~7번 과정은 좀 더 직관적이고 단순하게 할 수 있을 것 같은데 더 생각해봐야겠다.
p.s. 괜찮은 방법이 있다면 댓글로 공유 부탁드립니다~
'코딩테스트' 카테고리의 다른 글
[코딩테스트 기초] 회문문자열 판별(재귀함수, array splice을 이용하여 - javascript) (0) | 2022.02.20 |
---|---|
[코딩테스트 기본] 10진수를 2진수로 바꾸기 (Javascript) (0) | 2022.02.20 |
[프로그래머스 코딩테스트] 완전탐색 > 모의고사 (level 1) (0) | 2021.12.26 |
[코딩테스트] 2018 카카오 블라인드 테스트 - [1차]비밀지도 (Javascript) (0) | 2021.11.27 |
[코딩테스트] 2019 카카오 개발자 겨울 인턴십 - 크레인 인형뽑기(Javascript) (0) | 2021.11.22 |