Algorithm

프로그래머스 : 실패율 (42889)

KJihun 2023. 6. 20. 19:38
728x90
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

위의 문제를 보고 스테이지를 key 값, 실패율을 value값으로 구현하여 풀면 되겠다고 생각했다.

최근에 힘겹게 풀었던 문제들을 TIL로 자주 썼었는데, 이 문제는 특히나 어려웠다.

import java.util.*;
class Solution {
    public int[] solution(int N, int[] stages) {
        Map<Integer, Double> map = new HashMap<>();
        
        int answer[] = new int[N];
        // 1부터 N까지 map 생성
        for (int i = 0; i < N; i++) {
            map.put(i + 1, 0.0);
        }
        
        // stages를 확인 후 키값과 비교하여 ++
        for (int i = 0; i < stages.length; i++) {
            //키값 존재 시 +1
            if (map.containsKey(stages[i])) {
                double count = map.get(stages[i]) + 1;
                map.put(stages[i], count);
            }
        }

        //실패율 구하기
        for (Map.Entry<Integer, Double> entry : map.entrySet()) {
            int number = stages.length;
            Integer key = entry.getKey();
            Double value = entry.getValue();
            for (int i = 0; i < stages.length; i++) {
            		// stage에 도달하지 못한 user가 있다면 분모값이 될 number를 --;
                    if (key > stages[i]) {
                        number--;
                    }
                }
                // stage에 유저가 없다면 skip, 아니면 실패율을 value값으로 넣음
                if(value != 0){
                    map.put(key, value / number);
                }
            }

 

여기까지도 쉽진 않았지만 구현은 할 수 있었다. 하지만 실패율(value)로 정렬을 수행하여야 하는데

key값이 아닌 value값으로 정렬을 해 본 적이 없어 어떻게 정렬을 해야 할지 막막했다.

고민 후 value값으로 정렬할 수 있는 방법을 찾아봤다. 

찾다 보니 TreeMap이 눈에 들어왔다. key값으로 정렬하여 테이블에 저장한다고 한다.

하지만 value값으로 정렬해야 했기에 우선은 보류하였다.

그렇게 계속 찾다 보니 List로 덮어씌운 후 Steam을 사용하여 value값으로 정렬할 수 있는 방법이 있었다.

 

        
            // 정렬을 위해 Map.Entry를 리스트로 변환
            List<Map.Entry<Integer, Double>> entryList = new ArrayList<>(map.entrySet());

            // 밸류값으로 내림차순 정렬
            // entryList.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));

            // 밸류값으로 역정렬(reversed) 후, 
            // 밸류값이 같을 시 키값으로 오름차순 정렬
            entryList.sort(Map.Entry.<Integer, Double>comparingByValue()
                .reversed()
                .thenComparing(Map.Entry.comparingByKey()));

 

시간은 많이 걸렸지만 무사히 성공했다!

사용하게 된 메서드들을 하나하나 찾아봤다.


1. `.sort()`: 정렬을 정렬하는 메서드
2. `.comparingByValue()` :  밸류값을 기준으로 정렬을 수행하는 메서드

3. `.reversed()`: 정렬된 결과를 역순으로 바꾸는 메서드. 밸류값이 내림차순으로 정렬

4. `.thenComparing()`: 다음비교. 즉 동일한 밸류값이 존재할 시 수행하는 메서드
5. `.comparingByKey()`: 키값을 기준으로 정렬을 수행하는 메서드

 

 

 

이번 문제로 인해 hashMap을 value값으로 정렬하는 방법과 유용한 메서드들을 알게 되었고,

SortedMap 인터페이스를 구현해 key값으로 정렬하는 TreeMap을 알게 되었다.

앞으로는 key값으로 정렬해야 하는 map이 생길 시 TreeMap을 사용하고, 

알게 된 메서드들을 적극 활용하여 사용해야겠다.