JAVASCRIPT/코딩테스트

프로그래머스 레벨1 - 2022 KAKAO BLIND RECRUITMENT 신고 결과 받기 (JAVA)

진짠 2023. 2. 10. 13:20
728x90

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

문제

카카오 코테는 뭔가 설명이 길어서 읽기가 귀찮다.

 

하지만 레벨1이라서 그런지 귀찮음을 참고 읽다보면 이해가 어려운 편은 아니다.

 

신고횟수가 k회 이상인 유저의 계정을 정지시키는 알고리즘을 짜면 된다. 각 유저는 다른 유저를 여러번 신고할 수도 있고 한 유저를 반복 신고할 수도 있다.

 

문제를 보며 Hashmap을 사용해서 풀어야 쉽겠다는 생각을 했다. 값을 넣고 빼기가 더 직관적이고 간편하다는 생각이 들었다.

 

https://www.w3schools.com/java/java_hashmap.asp

 

Java HashMap

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

그리고 제일 중요한건 각 유저의 신고받은 횟수를 카운팅한 뒤 정지당한 사람의 수를 구하는 것. 띄어쓰기를 이용해 구분되어 있으니 split함수도 필요하다는 생각을 했다.

 

나는 map과 set을 이용하여 {신고받은사람 : [신고자1, 신고자2, ...]} 형태로 값을 저장하고 hashset의 size를 비교하여 정지당하는 사람의 수를 구해야겠다고 생각했다.

(글로는 매우 간단하게 계획이 선 것 같지만 이 생각을 하기까지 많은 시간이 걸렸다...)

 

제한사항

위에서도 말했듯 신고한 사람 id와 신고당한 사람 id가 띄어쓰기로 구분되어 있다는 사실을 짚고 넘어가야 한다.

 

자기 자신도 신고할 수 없다.

 

return 배열은 id_list에 있는 id의 인덱스 위치와 동일하게 각 유저가 받은 메일의 숫자를 담아주면 된다.

 

import java.util.*;
class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        Map<String, Integer> map = new HashMap<>(); //각 유저들을 맵으로 저장
        Map<String, HashSet<String>> rep = new HashMap<>(); //각 유저가 신고한 유저들을 맵으로 저장
        int[] answer = new int[id_list.length]; //신고메일을 받은 횟수를 저장하는 배열
        for(int i=0;i<id_list.length;i++) {
            map.put(id_list[i], i); 
            rep.put(id_list[i], new HashSet<>()); 
        }
        for(String s : report) {
            String[] sp = s.split(" ");
            String reporter = sp[0]; //신고한 사람
            String follower = sp[1]; //신고받은 사람
            rep.get(follower).add(reporter); //신고받은 사람이 KEY이고 신고한 사람들을 HASHSET에 ADD함
        }
        for(int i=0; i<id_list.length; i++) {
            HashSet<String> list = rep.get(id_list[i]);
            if(list.size() >= k) { //신고한 사람의 수가 K번 이상일 경우
                for(String name : list) {
                    answer[map.get(name)]++; //answer배열의 해당 유저 인덱스 위치의 값을 더해줌
                }
            }
        }
        
        return answer;
    }
}

여담이지만 자바는 라이브러리 import 작업이 너무 번거롭고 불편한 거 같다. 파이썬이 제일 편하다고 하는데 잘 모르니 js로..

 

먼저 map을 이용해 담을 것들을 변수로 만들어준다.

 

각 유저들의 id에 해당 id의 인덱스를 값으로 한 map 변수 하나, 신고한 사람과 신고당한 사람들을 나열하기 위해 hashmap, hashset을 사용하여 데이터를 가공한 rep 변수 하나.

 

첫번째 for문에서는 id와 그 아이디가 위치한 인덱스를 맵에 넣어주었다. 그리고 신고한 id도 rep에 넣어주었다.

 

두번째 for문에서는 파라미터로 받은 신고자 report를 추출해서 split을 사용해 신고한 사람, 신고받은 사람을 구분한 뒤 rep의 id 뒤에 넣어주었다.(그러니까 신고한 사람들이 hashset에 들어가는거다.)

 

마지막 for문에는 hashset에 들어간 신고한 사람들의 size가 파라미터 k보다 많을 경우 answer배열에 넣어주는 방식이다. 해당 인덱스가 모두 map변수에 들어가 있기 때문에 별도로 데이터를 가공할 필요 없이 해당 위치에 값을 1씩 더해준다.

 

결국 신고자가 신고한 사람 중 정지당한 사람의 숫자 = 신고자가 메일 받는 횟수  로 생각하여 문제를 푼 것이다.

 

비교

여러 함수를 이용한 깔끔한 코딩이 인상적이었다. 저 기능을 모두 파악해야지만 가능한 코드..저런 유창한 프로그래밍 언어를 구사하려면 얼마나 노력을 많이 했을까라는 생각이 들었다.

 

또 자바 본연의 기준인 객체지향 언어 사용해 충실하여 user를 객체로 분리한 뒤에 신고한 사람, 신고당한 사람, 이름을 조건에 맞게 카운팅하여 넣어주고 값을 추출한 코딩도 정말 멋있었다.

 

성능적으로도 내가 짠 코드보다 훨씬 좋았다.

 

총평

카카오는 들어가기 힘든 곳이구나. 하지만 꾸준히 노력한다면 기업이 요구하는 실력에 도달하는 것이 아주 불가능한 영역은 아니겠구나, 라는 생각이 들었다. 

 

무엇보다 세상엔 뛰어난 개발자들이 많고 정말 노력해야한다는 사실도 다시 한번 깨달았다.

 

그리고 레벨1이 이정도면 뒤로 가면 어떤 문제가 나올지.. 상상하기 싫지만 상상됐다.

 

출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges

728x90