Algorithm

[Algorithm] 프로그래머스_실패율_2019 KAKAO BLIND RECRUITMENT

cornarong 2021. 8. 15. 17:52

설명

슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.

이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.

  • 실패율은 다음과 같이 정의한다.
    • 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.

 

제한사항

  • 스테이지의 개수 N은 1 이상 500 이하의 자연수이다.
  • stages의 길이는 1 이상 200,000 이하이다.
  • stages에는 1 이상 N + 1 이하의 자연수가 담겨있다.
    • 각 자연수는 사용자가 현재 도전 중인 스테이지의 번호를 나타낸다.
    • 단, N + 1 은 마지막 스테이지(N 번째 스테이지) 까지 클리어 한 사용자를 나타낸다.
  • 만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.
  • 스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은 0 으로 정의한다.

예시 입력 / 출력

N stage result
5 [2, 1, 2, 6, 2, 4, 3, 3] [3,4,2,1,5]
4 [4,4,4,4,4] [4,1,2,3]

 

 

풀이 과정

1. HashMap에 스테이지 별로 넘어가지 못한 유저 인원수를 getOrDefault를 사용하여 넣는다.

 

2. 실패율을 담을 ArrayList를 하나 만들고 스테이지와 실패율을 담을 class를 하나 선언한다.

 

3. class를 Comparable사용하여 실패율을 오름차순으로, 만약 실패율이 같을 경우 작은 스테이지가 먼저 올 수 있도록 compareTo를 오버라이드하여 재정의한다. 

(*실패율은 duble타입이고 compareTo메소드의 return타입은 int로, 반환값 실패율을 대소비교하여 '1' 또는 '-1'로 return되도록 한다)

 

2. Hash를 반복문으로 돌려 해당 key(스테이지)이 '0'일 경우 해당 스테이지와 실패율 '0'을 ArryList에 타입에 맞게 클래스 객체를 생성하여 담아주고, key(스테이지가) '0'이 아닐 경우 실패율을 구한 후 클래스 객체를 생성하여 담아준다.

(*실패율을 구한 후 해당 스테이지의 인원을 전체유저에서 뺴준다 -> 실패율을 구할 때마다 전체인원이 감소한다.)

-> 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

 

실패율을 double타입으로 구해야 크고 낮은 정렬이 가능하기에 기존에 int타입으로 대부분의 문제들이 해결하다 double타입으로 구현하려다 보니 compareTo메서드를 포함하여 중간중간 로직구현에 난관이 많았다..

 

 

풀이

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

class Solution {

    static class St implements Comparable<St> { 
        int stage;
        double fail;
        public St(int stage, double fail) {
            this.stage = stage;
            this.fail = fail;
        }
        
        @Override
        public int compareTo(St o) {
            if (this.fail == o.fail) {
                return this.stage - o.stage;
            } else {
                if (this.fail > o.fail) {
                    return -1;
                } else {
                    return 1;
                }
            }
        }
    }

    public int[] solution(int N, int[] stages) {
        int[] answer = {};
        HashMap<Integer, Integer> hash = new HashMap<>();
        for (int i = 0; i < stages.length; i++) {
            hash.put(stages[i], hash.getOrDefault(stages[i], 0) + 1);
        }
        Double users = (double) stages.length;
        ArrayList<St> arr = new ArrayList<>();
        for (int i = 1; i <= N; i++) {
            if (hash.get(i) == null) {
                arr.add(new St(i, 0));
//                System.out.println(i+"번 스테이지 0명");
            } else {
                Double fail = (double) hash.get(i) / users;
                arr.add(new St(i, fail));
//                System.out.println(i+"번 스테이지 실패율="+fail);
                users = users - hash.get(i);
            }
        }
        Collections.sort(arr);
        answer = new int[arr.size()];
        for (int i = 0; i < arr.size(); i++) {
            answer[i] = arr.get(i).stage;
        }
        return answer;
    }
}