코딩 테스트

(Java) 프로그래머스 신고 결과 받기

로승리 2022. 5. 6. 03:18

작년 카카오 공채 문제였다. 당시 처음으로 코딩 테스트를 경험해보고자

지원해서 풀어봤지만.. 1문제밖에 못풀었었다.

 

문제를 읽고 오랜만에 구현 방법이 제대로 떠오르지 않았다.

Map을 이용해야 한다는 건 알겠는데 Map을 어떻게 이용해야 할지 

명확하게 떠오르지가 않았다.

 

그래서 이중 for문을 마구 쓰며 풀었다.

구현하면서도 이건 아닌데 싶었는데 딱히 방법이 없어 끝까지 해봤다.

답은 구해지는데 테스트 케이스 7~8개에서 시간 초과가 났다.

 

처음 작성한 코드

public int[] solution(String[] id_list, String[] report, int k) {
        int[] answer = new int[id_list.length];
        int[] cnt = new int[id_list.length];

        // 중복 제거
        String [] result = Arrays.stream(report).distinct().toArray(String[] :: new);
        System.out.println(Arrays.toString(result));
        for (int i = 0; i < id_list.length; i++) {
            for (int j = 0; j < result.length; j++) {
                String[] temp = result[j].split(" ");
                if(id_list[i].equals(temp[1])) {
                    cnt[i]++;
                }
            }
        }
        ArrayList<String> list = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
        for (int i = 0; i < cnt.length; i++) {
            if(cnt[i] >= k) {
                list.add(id_list[i]);
            }
        }

        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j < result.length; j++) {
                String[] temp = result[j].split(" ");
                if(list.get(i).equals(temp[1])) {
                    list2.add(temp[0]);
                }
            }
        }

        for (int i = 0; i < id_list.length; i++) {
            for (int j = 0; j < list2.size(); j++) {
                if(id_list[i].equals(list2.get(j))) {
                    answer[i]++;
                }
            }
        }

        return answer;
    }

 

다음날 다시 리펙토링을 하려고 했는데도

어떻게 Map을 사용할지 몰라서 검색해봤다.

답은 HashMap<String, ArrayList<String>>) 과 같이 Map value에 List를 넣을 수 있었다...

Map은 자주 사용하지 않아서 잘 몰랐는데 이번에 또 배우는 것 같다.

자바의 정석을 미루지 말고 다시 한번 읽어야겠다.

 

최종 코드

import java.util.*;
class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
                int[] answer = new int[id_list.length];

        // HashSet으로 중복제거
        HashSet<String> reportSet = new HashSet<>();
        for(String s : report) {
            reportSet.add(s);
        }

        // Key(신고당한사람) : Value(신고자) 로 HashMap 선언
        HashMap<String, ArrayList<String>> reportMap = new HashMap<>();
        for (String s : reportSet) {
            // split으로 문자열 나누기
            String[] temp = s.split(" ");
            String reporter = temp[0];
            String reportee = temp[1];
            ArrayList<String> list = reportMap.get(reportee);
            // value가 비어있다면
            if(reportMap.get(reportee) == null) {
                // 리스트 초기화
                list = new ArrayList<>();
            }
            list.add(reporter);
            reportMap.put(reportee, list);
        }

        // 신고자에게 정지 메일을 카운팅 하는 Hashmap 만들기
        HashMap<String, Integer> cntMap = new HashMap<String, Integer>();
        // reportMap에서 value list를 가져오기
        for(ArrayList<String> list : reportMap.values()) {
            // 그 값이 k보다 크다면
            if(list.size() >= k) {
                for(String s : list) {
                    // cntMap에 신고자를 key로 넣고 value에 메일 발송 카운트
                    cntMap.put(s, cntMap.getOrDefault(s, 0) + 1);
                }
            }
        }
        
        // 카운팅을 기반으로 answer 배열 채우기
        for (int i = 0; i < id_list.length; i++) {
            answer[i] = cntMap.getOrDefault(id_list[i], 0);
        }
        return answer;
    }
}