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

Bluewave·2024년 8월 14일

코테공부_java

목록 보기
54/99
post-thumbnail

문제

🎃 문제 바로가기

문제레벨정답률
신고 결과 받기Lv.139%

My Code

ㄴ 실패 코드

class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        int[] reportTotal = new int[id_list.length]; //전체 신고 횟수
        int[] emailNum = new int[id_list.length]; //내가 받을 이메일 수 
        
        for(int i = 0; i<report.length; i++){
            //띄어쓰기 기준으로 신고자와 신고받은사람 구분
            String from = report[i].split(" ")[0];
            String to = report[i].split(" ")[1];
            int cnt = 1;
            
            //이전 신고 이력 없으면 1 증가
            for(int j = i; j>0; j--){
                if(reportTotal[i] != reportTotal[j]){
                    cnt = 0;
                }
            }
            if(cnt == 0){
                reportTotal[searchId(to)]++;
                emailNum[searchId(from)]++;
            }
        }
        
        //신고 받은 횟수 k 이상이면 메일 수 +1
        for(int i = 0; i<reportTotal.length; i++){
            if(reportTotal[i] >= k){
                for(int j = 0; j<report.length; j++){
                    String from = report[i].split(" ")[0];
                    String to = report[i].split(" ")[1];
                    if(searchId(to) == i){
                        emailNum[searchId(from)]++;
                        
                    }
                }

            }
        }
        
        return emailNum;
    }
    
    public int searchId(String name){
        switch(name){
            case "muzi":
                return 0;
            case "frodo":
                return 1;
            case "apeach":
                return 2;
            case "neo":
                return 3;
        }
        
        return -1;
    }
}

구현하고자 했던 로직

  1. 전체 신고 횟수와 내가 받을 이메일 수 를 각각 배열로 선언
  2. report를 for문으로 돌면서 report 배열에서 신고자와 신고 받은 사람을 구분하여 String 변수에 저장
  3. reportTotal 배열을 탐색하면서 이전 신고 이력이 없다면 reportTotal 배열과 신고자 emailNum 1증가
  4. reportTotal 배열을 돌면서 신고 횟수가 k 이상인 사람은 그 사람을 신고한 사람들의 메일 수 1 증가

일단 지금 로직을 쓰면서 느낀건데 단순히 구현하고자 하니 너무 복잡한 문제인 것 같고, 알고리즘을 사용해야 해결될 것 같은데 감이 잘 안왔다..
그리고 마지막 부분에 searchId 라는 함수를 써서 해당 사용자의 index를 return 하게 했는데, 이 부분도 사실 매번 사용자가 다르게 입력된다는 점 ^^~


최적화 코드

class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        // 신고받은 횟수
        int[] reportTotal = new int[id_list.length];
        // 내가 받을 이메일 수
        int[] emailNum = new int[id_list.length];
        // 신고 관계 저장
        HashMap<String, Set<String>> reportMap = new HashMap<>();

        // 신고 관계를 저장
        for (String r : report) {
            String[] parts = r.split(" ");
            String from = parts[0];
            String to = parts[1];
            if (!reportMap.containsKey(to)) {
                reportMap.put(to, new HashSet<>());
            }
            reportMap.get(to).add(from);
        }

        // 신고 받은 횟수를 업데이트
        for (Map.Entry<String, Set<String>> entry : reportMap.entrySet()) {
            String to = entry.getKey();
            Set<String> fromSet = entry.getValue();
            int count = fromSet.size();
            int toIndex = searchId(to, id_list);
            if (count >= k) {
                for (String from : fromSet) {
                    int fromIndex = searchId(from, id_list);
                    emailNum[fromIndex]++;
                }
            }
        }

        return emailNum;
    }

    // id_list를 기준으로 id를 인덱스로 변환
    private int searchId(String name, String[] id_list) {
        for (int i = 0; i < id_list.length; i++) {
            if (id_list[i].equals(name)) {
                return i;
            }
        }
        return -1; // id_list에 없는 id
    }
}

이 코드는 내 코드를 기준으로 gpt 돌린거라 전체 로직은 비슷하다.

우선 switch 문으로 인덱스를 return 하는 함수 대신, id_list를 기준으로 equals 메서드를 활용해서 인덱스를 찾는 방식을 택하였다.
그리고 신고 관계를 저장할 때 내가 꼬였던 부분은 Map으로 해결하였다.
ㄴ 사실 머리로는 생각했는데 좀 귀찮아서 안함

그리고 Set을 이용해서 중복 신고를 방지하였다.
-> 여기까진 생각못함..


1단계인데 정답률이 30%대인게 의문이었는데 그럴만한 문제..인 것 같고 사실 Lv.1도 아닌 것 같음 한 Lv.3정도는 되는듯;
Map, Set의 경우 특히 내가 아직 자유롭게 쓰지 못하는 알고리즘이라 더 어려운 문제였던 것 같다.

profile
Developer's Logbook

0개의 댓글