프로그래머스 - 실패율

박철현·2023년 8월 26일

프로그래머스

목록 보기
46/80

프로그래머스 - 실패율

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.stream.Collectors;

class Solution {
	public int[] solution(int N, int[] stages) {
		// 실패율 : (도달했으나 아직 클리어x) / (도달한 플레이어 수)
		// 전체 스테이지 N, 멈춰있는 스테이지 번호 배열 stages
		// 실패율이 높은 스테이지 부터 내림차순
		// 1. stage에서 가장 작은 단계를 구한다.
		// 1-1. 만약 제일 작은 단계가 N하고 같으면, 해당 단계에서 전부 실패니까 제일 높은 실패율
		// -> 이 경우라면 N, 1~N 순서 반환
		// 2. 1~N 단계까지 각각 실패율을 구한다
		// 2-1. 1단계 실패 -> 1 / 전체 사용자 수, 2단계 실패 => 2 / 2단계 이상 도달한 사용자 ..
		// 3. 대소 비교 후 내림차순 정렬 반환

		// 1. stage에서 가장 작은 단계 구하기.
		int minStage = stages[0];
		for (int stage : stages) {
			if (minStage > stage) {
				minStage = stage;
			}
		}

		// 1-1. 제일 작은 단계가 전체 단계랑 같다 -> 해당 단계 전부 실패
		if (minStage == N) {
			int[] result = new int[N];
			result[0] = N;
			for (int i = 1; i < N; i++) {
				result[i] = i;
			}
			return result;
		}

		List<Double> fails = new ArrayList<>();
		// 2. 1~N 단계 실패율 각각 구하기
		for (int i = 1; i <= N; i++) {
			int stageCount = 0;
			int stageAllCount = 0;
			for (int j = 0; j < stages.length; j++) {
				if (stages[j] >= i) {
					stageAllCount++;
					if (stages[j] == i) {
						stageCount++;
					}
				}
			}

			// 스테이지에 도달한 유저가 없는 경우 0으로 정의(문제 조건)
			if (stageCount == 0) {
				fails.add(0.0);
			} else {
				double failPercent = (double)stageCount / stageAllCount;
				fails.add(failPercent);
			}
		}

		List<Double> sortedList = fails.stream().sorted(Collections.reverseOrder()).collect(Collectors.toList());

		// 중복 제거한 오름 차순
		LinkedHashSet<Double> setList = new LinkedHashSet<>(sortedList);

		List<Integer> resultList = new ArrayList<>();
		// 값 같은 "인덱스(들) + 1" 값을 찾아서 정답에 하나씩 넣기
		// 실패율이 똑같으면 앞의 단계부터 나오니깐 고려 안해도 됨
		for (Double a : setList) {
			for (int i = 0; i < fails.size(); i++) {
				if (a.equals(fails.get(i))) {
					resultList.add(i + 1);
				}
			}
		}

		return resultList.stream()
			.mapToInt(Integer::intValue)
			.toArray();
	}
}
  • stage에서 가장 작은 단계를 구한다.
    • 만약 제일 작은 단계가 N하고 같으면, 해당 단계에서 전부 실패니까 제일 높은 실패율
      • 이 경우라면 N, 1~N 순서 반환

위에가 아니라면

  • 1~N 단계까지 각각 실패율을 구한다.
    • 단계에 도달한 사용자가 없을 경우 실패율은 0으로 계산
  • 실패율이 들어있는 리스트를 오름차순 정렬한 리스트를 만들고, Set화 하여 중복을 제거한다
    • 이때 꼭 LinkedHashSet으로 해야 순서가 보장되어 올바른 답이 나옴
    • 순서가 이상해서 뭐지 싶었다..
  • Set에서 하나씩 꺼내서 원래 fails와 비교하며 인덱스+1을 결과에 넣는다.
    • 오름차순 정렬한 것과 원본 리스트의 값이 같으면 그 인덱스가 최대값
    • 하지만 0레벨이 아닌 1레벨 부터 진행하기에 인덱스+1값

도달한 사용자가 없을 경우 실패율에서 한번 걸리고(분모가 0이 되어 NaN.. 문제를 잘보자..진짜), 최소값에서 한번 걸리고, LinkedHashSet에서 한번 걸리고.. 다른 사람들 풀이 직관적 이라는 것도 봤는데 내 코드가 제일 이해하기 쉬울꺼같음 오래걸린 만큼 성장했길!

profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글