[programmers] Level0 최빈값 구하기 120812

iy·2025년 3월 11일

해당 문제는 문자열 중 가장 많이 존재하는 숫자 즉 최빈값을 구하는 문제이고, 최빈값이 여러 개일 때는 -1을 retun하면 된다.


✨ 제출 코드

import java.util.*;

class Solution {
    public int solution(int[] array) {
        int answer = 0;
        HashMap<Integer,Integer> map = new HashMap<>();
        
        int max = 0;
        for(int number : array) {
            map.put(number, map.getOrDefault(number,0) + 1);
            max = Math.max(max, map.get(number));
        }
        
        int count = 0; 
        for(Map.Entry<Integer,Integer> entry : map.entrySet()) {
            if(entry.getValue() == max) {
                count++; 
                answer = entry.getKey();
            }
        }
        return count == 1 ? answer : -1;
    }
}

HashMap을 이용해서 풀었다. 주어진 배열의 값은 key 값으로 이용해 value에 나오는 숫자를 기록했고, 해당 value를 Math.max를 이용해 최빈값을 확인해주었다.
Map.Entry를 이용해 map을 순회해 entry.getValue를 이용해 max 값과 일치하는 entry.getKey()를 answer에 담아주고 count 역시 +1 해주어 최빈값이 몇개인지 확인했다.
count가 1이 아니라면 최빈값의 수가 유일하지 않기 때문에 -1을 유일하면 answer값을 return 해주었다.


🐾 Map.Entry ?

Map.Entry는 Java의 Map 인터페이스 내부에 정의된 중첩 인터페이스로 Key-Value를 한 쌍으로 저장하는 객체를 의미한다.
Map 에 저장된 데이터의 순회가 필요할 때 사용한다.

❔ 해당 문제에서 왜 필요했는가

	for(Map.Entry<Integer,Integer> entry : map.entrySet()) {
            if(entry.getValue() == max) {
                count++; 
                answer = entry.getKey();
            }
        }

해당 문제는 map을 이용해 value값에 숫자 빈도수를 체크했다. Map을 사용한 이유는 key값은 중복이 되지 않고 getOrDefault 메서드의 시간복잡도가 대체적으로 O(1) 이므로 빠르게 동작이 가능하다고 판단했기 때문이다.

그러나 Map은 getKey()메서드로 key값 기준으로 value값을 찾는 건 가능하지만 value값을 기준으로 바로 값을 찾아오는 것이 불가능하다.
또한, 해당 문제는 최빈값의 유일성 역시 판단해야 했기 때문에 Map.Entry를 이용해 순회하면서 entry.getValue()로 max값과 일치하는 경우를 확인할 수 있었다.


👀 다른 방법은 없었나?

해당 문제를 풀고 꼭 모든 값을 순회해서 경우를 찾아야 하는지 의문이 들었다.

  • 다른 사람 풀이
import java.util.*;

class Solution {
    public int solution(int[] array) {
        int maxCount = 0;
        int answer = 0;
        Map<Integer, Integer> map = new HashMap<>();
        for(int number : array){
            int count = map.getOrDefault(number, 0) + 1;
            if(count > maxCount){
                maxCount = count;
                answer = number;
            }
            else  if(count == maxCount){
                answer = -1;
            }
            map.put(number, count);
        }
        return answer;
    }
}

해당 풀이를 보면 map의 값을 추가하면서 동시에 maxCount를 이용해 경우를 나누어 value값의 count가 maxCount를 넘어서면 answer에 해당 키 값을 담아주었다.
이렇게 값을 확인할 때 count 가 maxCount와 같아지면 answer에 -1, maxCount는 count를 담는다.
해당 조건에 따라 비교 후 해당 key 값과 count 값으로 map 값을 추가해준다.


🛠 회고

우선 Map.Entry에 대해 조금 더 이해할 수 있어서 좋았다. 하지만 문제를 풀 때 경우를 나누어서 값을 줄이는 방법을 생각해 봐야 할 거 같다. 값을 추가하는 반복문 안에서 모든 경우를 끝낼 수 있는 것을 추가로 불필요한 순회를 한 것이 조금 아쉽다.

0개의 댓글