문제

https://programmers.co.kr/learn/courses/30/lessons/42889


소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public int[] solution(int N, int[] stages) {
int[] failUsers = new int[N+2];
for (int stage : stages) {
failUsers[stage] += 1;
}

Map<Integer, Double> map = new HashMap<Integer, Double>();
double userCount = stages.length;
for (int i = 1; i <= N; i++) {
double value = 0.0;
if (failUsers[i] != 0 && userCount != 0) {
value = (failUsers[i] / userCount) * 100;
userCount -= failUsers[i];
}
map.put(i, value);
}

List<Integer> list = new ArrayList<Integer>(map.keySet());
Collections.sort(list, new Comparator<Integer>() {

@Override
public int compare(Integer o1, Integer o2) {
return map.get(o2).compareTo(map.get(o1));
}
});

int[] answer = list.stream().mapToInt(i -> i).toArray();
return answer;
}

흐름

  1. 유저 수(stages.length) 만큼 loop 돌면서 각 stage 별로 실패한 유저 수를 array에 저장한다.
  2. 스테이지별로 틀린 인원 수를 저장히기 위한 Map 변수를 하나 생성하고,
  3. 스테이지 수(N) 만큼 loop 돌면서 해당 스테이지에 실패한 사람이 있으면서, 전체 시도한 사람이 0명이 아닌 경우,
  4. $$ 해당 스테이지에서 실패한 유저 수 / 해당 스테이지에 도전한 유저 수 * 100 $$ 해서 해당 스테이지의 실패율을 구한다.
    • 이 때 스테이지에 도전한 유저 수는 이전 스테이지를 성공한 사람들 만이다.
  5. 이번 스테이지에서 실패한 유저들은 다음 스테이지에 도전 할 수 없으므로, 총 유저 수에서 실패한 유저 수를 제한다.
  6. 위에서 선언한 Map 변수에 key를 스테이지 번호로, value를 실패율로 하여 put 한다.
  7. 실패율을 저장한 Map을 Value 기준으로 내림차순 정렬을 한다.
  8. ArrayList를 int[]로 변환한다.
    • stream에 경우 속도가 느리므로, loop를 돌면서 직접 int[]로 만드는 방법이 퍼포먼스에 더 이로울 듯 하다.

결과

번호 속도
테스트 1 통과 (7.39ms, 52.6MB)
테스트 2 통과 (6.26ms, 54.7MB)
테스트 3 통과 (11.14ms, 54.2MB)
테스트 4 통과 (12.53ms, 58.2MB)
테스트 5 통과 (13.17ms, 63.3MB)
테스트 6 통과 (12.28ms, 52.3MB)
테스트 7 통과 (9.12ms, 53.5MB)
테스트 8 통과 (11.79ms, 58.6MB)
테스트 9 통과 (13.39ms, 61.4MB)
테스트 10 통과 (11.68ms, 55.8MB)
테스트 11 통과 (12.76ms, 59.8MB)
테스트 12 통과 (11.43ms, 60MB)
테스트 13 통과 (12.27ms, 62.7MB)
테스트 14 통과 (5.77ms, 54.3MB)
테스트 15 통과 (10.07ms, 54MB)
테스트 16 통과 (9.50ms, 55.6MB)
테스트 17 통과 (7.79ms, 53.4MB)
테스트 18 통과 (9.16ms, 54.8MB)
테스트 19 통과 (6.27ms, 52.8MB)
테스트 20 통과 (7.16ms, 53.2MB)
테스트 21 통과 (8.94ms, 55.3MB)
테스트 22 통과 (12.98ms, 62.7MB)
테스트 23 통과 (11.22ms, 58MB)
테스트 24 통과 (17.40ms, 59.7MB)
테스트 25 통과 (6.25ms, 52.9MB)
테스트 26 통과 (6.00ms, 52.3MB)
테스트 27 통과 (5.83ms, 50.4MB)

테스트 케이스

1
2
3
4
5
6
assertArrayEquals(new int[] {3,4,2,1,5}, test.solution(5, new int[] {2, 1, 2, 6, 2, 4, 3, 3}));
assertArrayEquals(new int[] {4,1,2,3}, test.solution(4, new int[] {4,4,4,4,4}));
assertArrayEquals(new int[] {2,1,3,4}, test.solution(4, new int[] {1,1,1,1,2}));
assertArrayEquals(new int[] {4,2,3,1}, test.solution(4, new int[] {3,2,5,4,2}));
assertArrayEquals(new int[] {7,6,2,3,5,4,1}, test.solution(7, new int[] {2, 1, 2, 6, 2, 4, 3, 3,7,5}));
assertArrayEquals(new int[] {1,2,3,4,5}, test.solution(5, new int[] {}));
  • Junit5로 테스트 했음.

  • 프로그래머스에서 제공하는 모든 케이스에 대한 것이 아니라,
    필자가 마음대로 넣은 것 이므로 이 소스를 통과하여도 프로그래머스에선 통과되지 못할 수 있음.


다른 멋진 분들의 해결방법