슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.
이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.
- 실패율은 다음과 같이 정의한다.
- 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수
전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.
- 스테이지의 개수 N은
1
이상500
이하의 자연수이다.- stages의 길이는
1
이상200,000
이하이다.- stages에는
1
이상N + 1
이하의 자연수가 담겨있다.
- 각 자연수는 사용자가 현재 도전 중인 스테이지의 번호를 나타낸다.
- 단,
N + 1
은 마지막 스테이지(N 번째 스테이지) 까지 클리어 한 사용자를 나타낸다.- 만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.
- 스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은
0
으로 정의한다.
N | stages | 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] |
import java.util.*;
class Solution {
public int[] solution(int N, int[] stages) {
int[] answer = new int[N];
HashMap <Integer, Double> failed = new HashMap<>();
int count = 0, passedCount = 0;
for (int i = 1; i <= N; i++) {
for (int j = 0; j < stages.length; j++) {
if (stages[j] >= i) count++;
if (stages[j] == i) passedCount++;
}
if(count == 0 & passedCount == 0) count = 1;
failed.put(i, ((double) passedCount / count));
count = passedCount = 0;
}
for (int i = 0; i < answer.length; i++) {
int key = 0;
double max = -1;
for (int k : failed.keySet()) {
if (max < failed.get(k)) {
max = failed.get(k);
key = k;
}
}
answer[i] = key;
failed.remove(key);
}
return answer;
}
}
💡
passedCount
는 스테이지에 도달했지만 클리어 하지 못한 플레이어의 수이고,count
는 스테이지에 도달한 플레이어의 수이다. 첫 번째 반복문에서 i는 각각의 스테이지를 가리키며 if문을 통해 조건에 맞으면 각각count
와passedCount
를 +1씩 올려 준다 스테이지에 도달한 유저가 없는 경우가 있을 수 있는데 이때는count
와passedCount
가 모두 0이므로count
를 1로 만들어 / by zero를 막아 준 후 실패율은 0이 될 수 있게 해 준다
💡 해시맵을 통해 스테이지 번호가 실패율을 저장하였으며 key가 스테이지 번호이고, value가 실패율이다
answer
배열에 스테이지 번호를 넣을 때는 keySet()을 통해 key를 통해 각각의 key에 맞는 value들을 비교할 수 있게 해 주었고, 실패율이 큰 스테이지부터answer
배열에 넣어 주고, 해당 key와 value를 삭제해 주었다 (삭제하게 되면 실패율이 같은 스테이지 번호를 따로 비교하지 않아도 된다 ❕)
생각보다 해결하는 데에 오래 걸렸던 문제이다... 해시맵에 스테이지 번호와 실패율 저장은 했지만 어떻게 비교를 해서 키값을 불러올지에 관한 고민도 많았었고 ArrayList를 사용할지 해시맵을 사용할지에 대해서도 고민이 많았지만 결국 해시맵으로 문제를 해결하였다 처음엔 단순 일반적인 for문을 통해 실패율들을 비교하면서 키값을
answer
에 넣고 지웠었는데 그럼 비는 키값에 대한 처리를 해 줄 수가 없어서 continue를 써 봤지만 아무튼 해결이 잘 안 됐었는데 keySet()을 이용하는 방법이 있다는 걸 알게 되고 이 방법으로 해결할 수 있어서 뿌듯하였다... 🤩