알고리즘 공부/프로그래머스

[프로그래머스] 2022 KAKAO BLIND RECRUITMENT - 신고 결과 받기

pa_songsong 2022. 4. 14. 23:22

출처

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

 

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

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

programmers.co.kr

 

제출 코드

import java.util.*;

class Solution {
    public int[] solution(String[] id_list, String[] report, int cnt_k) {
        //id_list에서 신고자가 신고한 사람들 추가위해 생성
        //ex) prodo - muzi, neo
        ArrayList<String>[] arr = new ArrayList[id_list.length];
        for(int i =0; i<arr.length; i++){
            arr[i] = new ArrayList<>();
        }
        
        //추가한 사람들 중복 안되게 hs 사용 
        HashSet<String> hs = new HashSet<>();
        for(int i = 0; i<report.length; i++){
            String[] s = report[i].split(" ");
            
            //기존에 추가되었었는지 확인 -> 안하면 에러 
            if(hs.contains(report[i])){
               continue; 
            }
            hs.add(report[i]);
            
            //id_list순서 찾아서 값 넣기 
            for(int j = 0; j<id_list.length; j++){
                 if(s[0].equals(id_list[j])){
                    arr[j].add(s[1]);
                }
            }
        }
        
        
        //신고당한 횟수 계산
        hs = new HashSet<>();
        HashMap<String, Integer> hm = new HashMap<>();
        for(int i = 0; i<report.length; i++){
            //이미 들어가 있는 값이면 패스 
            if (!hs.contains(report[i])) {
                //추가 후 배열로 잘라서 신고 횟수 추가하기 
                String[] s = report[i].split(" ");
                //s[0] 신고자, s[1] 피신고자 
                hm.put(s[1], hm.getOrDefault(s[1], 0) + 1);
                hs.add(report[i]);
            } 

        }
        
        //신고한 아이디 리스트와 비교해 신고 성공한 횟수 순서대로 추가 
        int[] answer = new int[id_list.length];
        for(int i = 0; i<arr.length; i++){
            for(int k = 0; k<arr[i].size(); k++){
                // System.out.println("i : "+i+arr[i].get(k));
                //hm에 이름 가지고 있으면 
                if(hm.containsKey(arr[i].get(k))){
                    //갯수 가져와서 k보다 큰지 비교 
                    if(cnt_k <= hm.get(arr[i].get(k))){
                        answer[i]++;
                    }
                }
            }
        }
        
        //각 유저별 신고 성공한 횟수담긴 배열 리턴  
        return answer;
    }
}

 

좀 더 괜찮게 수정한 코드

시작할때 중복을 제거하고 시작하면 중간중간에 중복된 것을 고려할 필요가 사라집니다.

for문 대신 for-each를 써서 값을 가져옵니다.

해시맵 내부에 ArrayList를 사용해서 신고자 수를 리스트 형식으로 넣어줍니다. 이때, 비었다면 ArrayList초기화를 수행해주어야합니다.

import java.util.*;

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

        //중복제거 후 시작
        HashSet<String> removeDupl = new HashSet<>();
        for (String rep : report) {
            removeDupl.add(rep);
        }

        // report에서 각 사람이 신고당한 횟수 countHash으로 정의
        HashMap<String, ArrayList<String>> hm = new HashMap<>();
        for (String rep : removeDupl) {
            String[] s = rep.split(" ");
            String reporter = s[0];
            String reportee = s[1];

            ArrayList<String> repList = hm.getOrDefault(reportee, null);
            //비었을 경우 ArrayList초기화 필수 
            if (repList == null) {
                repList = new ArrayList<>();
            }

            repList.add(reporter);
            hm.put(reportee, repList);//신고당한사람 , 신고자 리스트 
        }

        // hm기반으로 report해시 생성 
        HashMap<String, Integer> repHash = new HashMap<>();
        //신고자리스트 받기 
        for (ArrayList<String> repList : hm.values()) {
			//신고자리스트 수가 k보다 크면 신고 성공 
            if (repList.size() >= k) {
            	//신고자 리스트 돌아서 repHash에 신고자 당 신고 횟수 증가
                for (String reporter : repList) {
                    repHash.put(reporter, repHash.getOrDefault(reporter, 0) + 1);
                }
            }
        }

        // 정답배열에 옮기기 
        for (int i = 0; i < id_list.length; i++) {
            answer[i] = repHash.getOrDefault(id_list[i], 0);
        }

        return answer;
    }
}