코딩 테스트 준비-신고 결과 받기

Adam·2022년 2월 27일
0

코딩 테스트

목록 보기
1/3

쿠버네티스를 공부함과 동시에 알고리즘 공부 역시 꾸준히 해 나갈 생각이다.
우선 프로그래머스에 있는 문제들 부터 풀고 정리를 해볼 생각인데, 이 중 가장 먼저 푼 문제인 "신고 결과 받기"의 풀이에 대해서 적어보려 한다.
해당 문제는 2022년 카카오 블라인드 채용에 나온 문제라고 하며, 개인적으로 레벨 1의 문제 치고는 난이도가 있다고 생각하였다.

문제

신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다.

각 유저는 한 번에 한 명의 유저를 신고할 수 있습니다.
신고 횟수에 제한은 없습니다. 서로 다른 유저를 계속해서 신고할 수 있습니다.
한 유저를 여러 번 신고할 수도 있지만, 동일한 유저에 대한 신고 횟수는 1회로 처리됩니다.
k번 이상 신고된 유저는 게시판 이용이 정지되며, 해당 유저를 신고한 모든 유저에게 정지 사실을 메일로 발송합니다.
유저가 신고한 모든 내용을 취합하여 마지막에 한꺼번에 게시판 이용 정지를 시키면서 정지 메일을 발송합니다.
다음은 전체 유저 목록이 ["muzi", "frodo", "apeach", "neo"]이고, k = 2(즉, 2번 이상 신고당하면 이용 정지)인 경우의 예시입니다.

위 예시에서는 2번 이상 신고당한 "frodo"와 "neo"의 게시판 이용이 정지됩니다. 이때, 각 유저별로 신고한 아이디와 정지된 아이디를 정리하면 다음과 같습니다.

따라서 "muzi"는 처리 결과 메일을 2회, "frodo"와 "apeach"는 각각 처리 결과 메일을 1회 받게 됩니다.

이용자의 ID가 담긴 문자열 배열 id_list, 각 이용자가 신고한 이용자의 ID 정보가 담긴 문자열 배열 report, 정지 기준이 되는 신고 횟수 k가 매개변수로 주어질 때, 각 유저별로 처리 결과 메일을 받은 횟수를 배열에 담아 return 하도록 solution 함수를 완성해주세요.

풀이

해당 문제는 해시맵을 사용하면 어렵지 않게 풀 수 있었다.
기본적인 로직은 다음과 같다.
1. 각 유저가 신고 당한 횟수를 기록할 array 생성
2. 각 유저가 신고한 HashMap<String, ArrayList>을 생성, 이 때 키 값은 신고한 유저, 밸류는 신고 당하는 유저의 id_list 내의 인덱스 값으로 설정해준다.
3. report를 set에 담아 중복값을 제거해준다.
4. 해당 set을 돌며 split 메써드로 신고한 사람과 신고 당하는 사람으로 구분
5. 신고 당한 사람의 인덱스 값을 구해와 1번에서 생성한 array의 값을 올려준다.
6. 2번에서 만든 리스트에 신고한 사람을 키값으로 인덱스를 밸류 값으로 append 해준다(이때 인덱스를 get했을때 null일 경우 새 arrayList를 append 해준다)
7. k 값 보다 큰 값을 담을 arrayList를 생성해 1번에서 생성한 array 중 k보다 큰 값의 인덱스를 넣어준다.
8. 2번에서 만든 HashMap을 순회하면서 7번에서 만든 arrayList 값 중 밸류가 들고 있다면 answer의 해당 인덱스 값을 1 더해준다.

  import java.util.*;
class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        int[] answer = new int[id_list.length];
        int[] totalReport = new int[id_list.length];
        HashMap<String, ArrayList<Integer>> dic = new HashMap<String, ArrayList<Integer>>();
        Set<String> noDup = new HashSet();
        for(String s : report){
            noDup.add(s);
        }
        for(String s : noDup){
            String reporter = s.split(" ")[0];
            String reportee = s.split(" ")[1];
            int index = Arrays.asList(id_list).indexOf(reportee);
            totalReport[index]++;
            if (dic.get(reporter) == null) {
                dic.put(reporter, new ArrayList<Integer>());
            }
            dic.get(reporter).add(index);
        }
        ArrayList<Integer> over = new ArrayList();
        for(int i=0; i<totalReport.length; i++){
            if(totalReport[i]>=k){
                over.add(i);
            }
        }
        for(String s : dic.keySet()){
            for(int i=0; i<over.size(); i++){
                if(dic.get(s).contains(over.get(i))){
                    answer[Arrays.asList(id_list).indexOf(s)]++;
                }
            }
        }
        return answer;
    }
}

후기

문제 자체는 매우 직관적이고 간단하다고 생각했지만, 막상 이걸 코드로 구현하는 것은 생각만큼 쉽지 않았다.
내가 작성한 코드에 반복문이 많이 들어가서 효율성 테스트에서 실패할 줄 알았으나 다행히 통과하였다.
로직을 짜고 테스트 하는데 까지 대략 30분 조금 넘게 걸렸던 것 같은데, 더 많이 그리고 꾸준히 공부해봐야 할 것 같다.

profile
Keep going하는 개발자

0개의 댓글