본문 바로가기
개인 공부/알고리즘

[ 프로그래머스 ] 실패율

by 킴도비 2024. 5. 3.

📔 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

  • 문제 내용
스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수인 실패율 구하고, 실패율 순으로 스테이지 정렬하기

 

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

 

📖 문제 풀이

너무 예전에 풀고 한참 뒤에 블로그를 적어서..기억이 좀 애매모호 하지만? 적어보자면

 

일단 실패율의 정의를 먼저 고민했다.

 

                  스테이지 도달, 아직 클리어 X
실패율 =  ------------------------------------------
                              스테이지 도달

 

그다음 stages[]를 정렬을 해주었다.

 

전체 스테이지 + 1 사이즈 값으로 totalStage를 생성해 주었다. 왜냐하면 최종까지 다 깬 사람을 세기 편하게 하기 위해서이다.

 

그리고 스테이지가 1부터 시작하니 비교 값 + 1으로 해서 totalStage에서는 -1인 인덱스에 넣어 주었다.

 

그 다음 각 맵 별로 실패율을 구해야 했기에 Hashmap으로 Integer로 스테이지, Double로 각 스테이지 실패율을 저장해 주기 위해 각각 설정을 하였다.

 

아 그리고 최종적으로 구하는 것은 실패율이 높은 순으로 스테이지를 정렬해야 하는 것이기 때문에 꼭 key와 value 형식이거나 2차원 배열 쓰면 좋을 것 같다.

 

그 다음 player와 success라는 변수를 만들었다. 그러면 success / player가 실패율이 될 것이다.

 

그런데 여기서 주의할 점은 만약 0 / player가 된다면 코드 오류가 나기 때문에 이 경우에는 0으로 직접 지정해 주었다. 아닐 시에는 실패율 넣어주기

 

근데 이게 앞에서 부터 해도 되지만 직접 손으로 계산해 보니 맨 뒷 스테이지부터 계산하니 빠르게 계산이 되었다.

 

이 순으로 빠르게 계산이 가능했다.

 

 

이렇게 계산한 후 key 값을 ArrayList에 담아주었다.

 

그 다음 compareTo를 이용하여 정렬해 주었다. value 값으로 비교해서 key 값을 정렬해 주는 것이다.

 

그 이후 해당 값을 int[] 배열에 keySet 배열 + 1로 해서 스테이지를 만들어주면 끝!

 

그렇다면 코드 완성이다!

 

 소스 코드

import java.util.*;

class Solution {
    public int[] solution(int N, int[] stages) {
        // 실패율 = 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수
        
        // 전체 스테이지의 개수 N
        // 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages
        // 실패율이 높은 스테이지부터 내림차순으로 스티이지의 번호가 담긴 배열을 return
        
        int[] totalStage = new int[N + 1];
        

        // 보기 편하게 변경
        Arrays.sort(stages);
        
        
        for(int i = 0; i < stages.length; i++){
            for(int j = 1; j <= N + 1; j++){
                if(stages[i] == j) totalStage[j - 1] += 1;
            }
        }
        
        HashMap<Integer, Double> fail = new HashMap<>();
        
        int player = totalStage[N];
        int success = totalStage[N -1];
        
        for(int x = N - 1; x > -1; x--){
            
            success = totalStage[x];
            player += totalStage[x];
            
            if(success != 0){
                // int / int 면 소수점 계산 안돼서 0으로 나옴
                fail.put(x, (double)success/player);
            } else {
                fail.put(x, 0.0);
            }
        }
        
        List<Integer> keySet = new ArrayList<>(fail.keySet());
        
        keySet.sort((o1, o2) -> fail.get(o2).compareTo(fail.get(o1)));

        int[] answer = new int[N];
        
        int cnt = 0;
        
        for(int x : keySet){
            answer[cnt++] = x + 1;
        }
        
        return answer;
    }
}

 

어려운 건 아니지만 0 처리를 하는 것이 매우 중요했고, 이걸 또 저장해서 비교하는 부분이 정말 중요했다!