코딩테스트
[ 프로그래머스 ] 실패율
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
[ 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을 하고 싶다면 위 방식을 사용하면 된다.