Intro

코딩 테스트 문제 풀이 경험이 필요하다고 생각해 초반에 풀었던 문제 중 하나입니다. 카카오 문제는 해당되어있는 레벨에 존재하는 타 문제에 비하여 문제가 복잡하며, 설명이 많아 친절한것 같지만... 정보의 홍수같은 느낌이라 오히려 문제에서 중요한 포인트를 놓치기 쉽습니다.
초반에 푼 문제라 구현에 급급하여 코드가 약간 지저분할 수 있습니다.

문제




키포인트

  • report 배열에 각 아이템 첫번째에는 신고한 사람이, 2번째에는 신고당한 사람이 저장됩니다.
  • report 배열의 아이템은 String 형태이고 신고한 사람과 신고 당한사람은 공백 " "으로 구분되는데 이걸 분리할 수 있는 기본 함수가 존재합니다.
  • 한 사람이 동일한 사람을 여러번 신고해도 1번만 처리됩니다. (비슷한 동작을 하는 자료구조가 존재합니다.)
  • 아이디:신고당한횟수(타인이 이 아이디를 신고한 횟수), 아이디:신고한아이디 => 이 두가지 형태의 데이터가 있다면 정답을 구할 수 있습니다.

풀이

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


class Solution {
    private Map<String, Integer> reportedCntMap = new HashMap<>();
    private Map<String, List<String>> reportMap = new HashMap<>();
    private List<String> enforcedList = new ArrayList<>();
    private Map<String, Integer> mailMap = new HashMap<>();

    public int[] solution(String[] id_list, String[] report, int k) {
        int[] answer = new int[id_list.length];
        // 유저별로 신고당한 횟수
        for(String item : report) {
            String[] splittedItem = item.split(" ");
            String reporter = splittedItem[0];
            String reportee = splittedItem[1];
            if( reportIsDuplicated(reporter, reportee) == false) {
                logReport(reporter, reportee);
                increaseReported(reportee);
            }
            if(reportedCntMap.get(reportee) == k || reportedCntMap.get(reportee) > k) {
                if(enforcedList.contains(reportee) == false) enforcedList.add(reportee);
            }
        }

        // 유저가 신고한 ID중 정지된 id
        for(String key : reportMap.keySet()) {
            int cnt = 0;
            List<String> reporteeList = reportMap.get(key);

            for(String reportee : reporteeList) {
                if(enforcedList.contains(reportee)) cnt += 1;
            }

            mailMap.put(key, cnt);
        }

        makeDefaultToMailMap(id_list);

        for(int i = 0; i < id_list.length; i++) {
            answer[i] = mailMap.get(id_list[i]);
        }

        return answer;
    }

    private boolean reportIsDuplicated(String reporter, String reportee) {
        List<String> reporteeList = reportMap.get(reporter);
        boolean result = false;

        if( reporteeList == null ) return result;

        for(String reporteeFromList : reporteeList) {
            if(reporteeFromList.equals(reportee)) result = true;
        }
        return result;
    }

    private void makeDefaultToMailMap(String[] id_list) {
        for (String id : id_list) {
            if (mailMap.containsKey(id) == false) {
                mailMap.put(id, 0);
            }
        }
    }

    private void logReport(String reporter, String reportee) {
        List<String> newReporteeList = null;

        if (reportMap.size() == 0 || reportMap.containsKey(reporter) == false) {
            newReporteeList = new ArrayList<>();
        } else {
            newReporteeList = reportMap.get(reporter);
        }
        newReporteeList.add(reportee);
        reportMap.put(reporter, newReporteeList);
    }

    private void increaseReported(String reportee) {
        if (reportedCntMap.size() == 0 || reportedCntMap.containsKey(reportee) == false) {
            reportedCntMap.put(reportee, 1);
        } else {
            reportedCntMap.put(reportee, reportedCntMap.get(reportee) + 1);
        }
    }
}

출처

프로그래머스 - lv1 - 신고결과받기

0개의 댓글