본문 바로가기
[IT] 알고리즘

[JAVA][프로그래머스] Lv1 신고 결과 받기 (자바 풀이 및 코드)

by 오리엔탈킴 2022. 5. 13.

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

 

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

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

programmers.co.kr

 

Input

  • id_list : 전체 유저의 ID 배열
["muzi", "frodo", "apeach", "neo"]

 

  • report : "신고한유저 신고당한유저"의 배열
["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"]

 

  • k : 특정 유저의 신고 횟수가 k보다 같거나 클경우, 그 유저를 신고한 사람에게 메일 발송

 

Output

id_list에 순서대로, 각 유저가 받은 메일의 수의 배열. 즉, 내가 신고한 사람들 중 k번 이상 신고를 받은 사람의 수

[2,1,1,0]

 

풀이

제일 먼저, Input으로 텍스트가 주어지지만 결국 User를 Index로 맵핑해서 풀이를 해야 해서, UserId : Index ("muzi" : 1)를 저장하는 Map을 먼저 만들었습니다. 

Map<String,Integer> idMap = new HashMap<>();
for(int i=0; i<id_list.length; i++) idMap.put( id_list[i], i );

 

다음으로는 Int로 구성된 Set을 담는 List를 전체 유저 수 만큼 생성하였습니다. Set을 사용한 이유는 중복 신고의 경우 1개로 친다는 제약조건 때문입니다. 

List< HashSet<Integer> > setList = new ArrayList<>();
for(int i=0; i<id_list.length; i++) setList.add(new HashSet<Integer>());

 

 

위 List는 List(1)의 Set에 2과3이 들어 있다고 하면, 1번을 신고한 사람은 2와 3이라는 의미로 사용되도록 report 배열을 읽어서 idMap에서 유저의 index 번호를 가져와 데이터를 등록을 합니다.

for(String str : report){
            setList.get( idMap.get(reportedId) ).add( idMap.get(userId) );
        }

 

이제 List의 set을 하나씩 가져와 나를 신고한 사람의 수 (Set의 사이즈)가 k 이상이면, answer 배역에서 신고한 사람에게 +1을 해줍니다.

for(int i=0; i<id_list.length; i++){
            if( setList.get(i).size() >= k ){
                for( int reportMan : setList.get(i) ) answer[reportMan]++;
            }
        }

 

코드

제가 푼 전체 코드는 아래와 같습니다. 막상 푸니 문제는 어렵진 않은 것 같은데, 문제 자체가 좀 복잡하게 되어 있어서 이해하는데 좀 걸리기는 했네요.. 직관적으로는 푼 것 같은데, 성능은 그리 좋은 편은 아닌 것 같습니다. 더 효율적인 방법이 많이 있기는 할 것 같네요..

    // set을 담는 List 생성
    static List< HashSet<Integer> > setList = new ArrayList<>();

    public int[] solution(String[] id_list, String[] report, int k) {
        
        // 이름 | index로 구성 된 Map을 생성
        Map<String,Integer> idMap = new HashMap<>();
        for(int i=0; i<id_list.length; i++) idMap.put( id_list[i], i );  

        // set List 초기화 (유저 수 만큼 set을 담은 리스트 생성)
        setList.clear();
        for(int i=0; i<id_list.length; i++) setList.add(new HashSet<Integer>());

        StringTokenizer st;
        String userId, reportedId;
        for(String str : report){
            st = new StringTokenizer(str);
            userId = st.nextToken();
            reportedId = st.nextToken();
            
            // List(0)의 set에는 0을 신고한 유저 index가 저장
            setList.get( idMap.get(reportedId) ).add( idMap.get(userId) );
        }

        int[] answer = new int[id_list.length];

        for(int i=0; i<id_list.length; i++){
            // i 유저를 신고한 인원 = set의 사이즈
            // set size가 k보다 크면 메일이 발송됨
            // set안에 i를 신고한 유저 번호이므로 answer 배열에 1씩 더해 줌
            if( setList.get(i).size() >= k ){
                for( int reportMan : setList.get(i) ) answer[reportMan]++;
            }
        }

        return answer;
    }

 

 

반응형

댓글