문제 자체는 간단하다.
stages 정보를 바탕으로 각 Stage 별 도착 인원 수와 시도 중인 인원 수를 먼저 계산한다.
계산한 값을 바탕으로 실패율을 구하고 이를 기준으로 정렬한다.
정렬된 순서에 맞게 각 stage 번호를 반환하면 된다.
Stage 클래스는 Stage와 관련된 정보를 가진다.
class Stage {
int num; // Stage 번호
int arrive = 0, trial = 0; // 각각 도착 인원, 시도 중인 인원
double failure; // 실패율
public Stage(int num) {
this.num = num;
}
}
주어진 N에 맞추어 1번부터 N번까지의 Stage를 생성한다.
solution의 stages 인자의 변수명을 S로 바꾸어 해결하였다.
List<Stage> stages = IntStream.rangeClosed(1, N)
.mapToObj(Stage::new)
.collect(Collectors.toList());
주어진 S의 정보를 바탕으로 stages의 실패율을 계산한다.
계산 방법은 stages를 하나식 탐색한다.
탐새할 때는 S의 정보를 바탕으로 arrive와 trial를 우선 계산하다.
이후 failure를 계산한다.
stages.forEach(stage -> stage.update(S));
public void update(int[] S) {
for (int s : S) {
if (s >= num) arrive++;
if (s == num) trial++;
}
calcAvg();
}
실패율을 모두 계산하였으면 이를 기준으로 정렬한다.
이 때 내림차순으로 정렬해야 한다.
stages.sort(Comparator.comparingDouble(s -> -s.failure));
정렬이 완려되었으면 List를 int[]로 변환하여 반환한다.
return stages.stream().mapToInt(stage -> stage.num).toArray();
위의 모든 과정들은 사실 Stream으로 처리할 수 있다.
따라서 하나의 Stream으로 처리한다.
return IntStream
.rangeClosed(1, N)
.mapToObj(Stage::new) // Stage 생성
.peek(stage -> stage.update(S)) // 실패율 계산
.sorted(Comparator.comparingDouble(s -> -s.failure)) // 실패율 정렬
.mapToInt(Stage::getNum).toArray(); // 변환 및 반환
class Solution {
public int[] solution(int N, int[] S) {
return IntStream
.rangeClosed(1, N)
.mapToObj(Stage::new)
.peek(stage -> stage.update(S))
.sorted(Comparator.comparingDouble(s -> -s.failure))
.mapToInt(Stage::getNum).toArray();
}
}
class Stage {
int num;
int arrive = 0, trial = 0;
double failure;
public Stage(int num) {
this.num = num;
}
public void update(int[] S) {
for (int s : S) {
if (s >= num) arrive++;
if (s == num) trial++;
}
calcAvg();
}
public void calcAvg() {
failure = arrive == 0 ? 0 : trial / (double) arrive;
}
public int getNum() {
return num;
}
}