📔 문제
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
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 처리를 하는 것이 매우 중요했고, 이걸 또 저장해서 비교하는 부분이 정말 중요했다!
'개인 공부 > 알고리즘' 카테고리의 다른 글
[ 프로그래머스 ] 등수 매기기 (0) | 2024.05.28 |
---|---|
[ 프로그래머스 ] 방문 길이 (0) | 2024.05.09 |
[ 프로그래머스 ] 행렬의 곱셈 (0) | 2024.03.25 |
[프로그래머스] 즐겨찾기가 가장 많은 식당 정보 출력하기 풀이 (0) | 2023.02.03 |
[프로그래머스] 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기 풀이 (0) | 2023.02.02 |