코딩테스트

[ 프로그래머스 ] 실패율

Adose 2024. 12. 3. 17:43

📌요구 사항 정리

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

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

 

📌 제약 조건

  • 스테이지의 개수 N은 1 이상 500 이하의 자연수이다.
  • stages의 길이는 1 이상 200,000 이하이다.
  • stages에는 1 이상 N + 1 이하의 자연수가 담겨있다.
  • 만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.
  • 스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은 0 으로 정의한다.

 

📌 첫번째 통과 코드 

public static int[] solution(int StageNumber, int[] stages) {
    int  [] countStage = new int[StageNumber+2];
    // +2가 되는 과정
    // +1 하는 이유 : stage 는 1부터 시작하기 때문에 +1을 해야 한다.
    // +1 하는 이유 : 최종 스테이지 클리어 한 사람은  다음 단계의 번호를 가지고 있기 때문에 +1을 해야 한다.
    //그래서 배열의 크기를 +2를 하게 되었다.

    double user =stages.length;
    //확률로 계산하기 위해서 double형으로 선언했다.


    for(int i=0;i<stages.length;i++) {
        countStage[stages[i]]+=1;
        //stages[] 인원을 countStage의 인덱스로 매칭해주었다.
        //이것을 통해 스테이지 별 인원수를 알 수 있다.
    }

    HashMap<Integer, Double> failCount = new HashMap<>();
    //스테이지별 실패율을 확인하기 위해서 HashMap으로 선언했다.

    for(int i=1;i<StageNumber+1;i++){
        if(countStage[i]==0){
            //스테이지에 도전자가 없다면, 해당 스테이지를 건너간 것이기 때문에 실패율은 0으로 설정한다.
            failCount.put(i,0.0);
        }
        failCount.put(i,countStage[i]/user);
        //스테이지별 실패율을 HashMap에 저장해준다.
        user-=countStage[i];
        //스테이지에 남아있는 인원들은 총 인원에서 제외해준다.
    }

    return failCount.entrySet().stream().sorted(((o1, o2)
            -> Double.compare(o2.getValue(),o1.getValue()))).mapToInt(Map.Entry::getKey).toArray();


}
  • 이 방법으로 처음 문제를 풀어봤고, 두번째 방법으로 다시 풀이를 해보았다. 
  • 이 방식을 사용했을때 compare의 내림차순 방식이 익숙하지 않아서 Comparable, Comparator 의 개념을 정리 했다. 
  • 문제 풀때 정리했던 개념들 

https://dose-blog.tistory.com/entry/java-Comparator-Comparable-%EC%B0%A8%EC%9D%B4

 

[ java ] Comparator, Comparable 차이

📌 Comparator, Comparable 사용이유primitive 타입(int, double 등)의 실수 변수는 부등호를 통해 두 변수를 비교할 수 있다.→ 기본 자료형이기 때문에 부등호로 쉽게 비교가 가능하다. ❓ 그렇다면 새로

dose-blog.tistory.com

https://dose-blog.tistory.com/entry/java-Comparable-Comparator-%EC%99%80-%EC%A0%95%EB%A0%AC%EC%9D%98-%EA%B4%80%EA%B3%84

 

[ java ] Comparable, Comparator 와 정렬의 관계

📌 자바의 정렬 ?Java에서의 정렬은 특별한 정의가 되어있지 않는 한 오름차순을 기준으로 한다.Arrays.sort(), Collections.sort() 모두 오름차순을 기준으로 정렬이 된다. ✏️  오름차순 정렬 방식int

dose-blog.tistory.com

 

 

📌 두번째 통과 코드 

public int [] solution(int n, int[] stages){
    int nPlayers = stages.length;
    int [] stagePlayers = new int[n+2];

    for(int player : stages){
        stagePlayers[player] +=1;
    }

    List<stageVa> countStagePlayer = new ArrayList<>();
    for(int i=1;i<=n;i++){
        double fail = stagePlayers[i]/(double)nPlayers;

        countStagePlayer.add(new stageVa(i,fail));
        nPlayers-=stagePlayers[i];
    }

    return countStagePlayer.stream().sorted().mapToInt(stageVa -> stageVa.stage).toArray();

}

public class stageVa implements Comparable<stageVa> {
    double fail;
    int stage;

    public stageVa(int stage,double fail) {
        this.fail = fail;
        this.stage = stage;
    }


   @Override
    public int compareTo(stageVa o) {
        if(fail < o.fail){
            return 1;
        }
        if(fail > o.fail){
            return -1;
        }

        return 0;
    }

}
  • class를 만든 후에 compareTo를 사용해서 비교를 해주었다.
    • compareTo를 사용할때는 부등호 방향을 바꾸어서 내림차순으로 정렬될 수 있도록 해주었다.  
  • Collection과 Stream의 개념을 알고있는게 문제 풀때 도움이 될 것 같다 ( 조금 빨리, 쉽게 풀 수 있음) 

 

return countStagePlayer.stream().sorted((a,b) -> Double.compare(b.fail,a.fail))
        .mapToInt(stageVa -> stageVa.stage).toArray();
  • compareTo를 구현하지 않고 바로 return을 하고 싶다면 위 방식을 사용하면 된다.