본문 바로가기
Algorithm/Programmers

[Programmers] Lv.0 | 최빈값 구하기 | Java

by unknownomad 2025. 11. 5.

문제

https://school.programmers.co.kr/learn/courses/30/lessons/120812

 

풀이

① 한방에 푸는 법 (코테용, 짧고 효율적인 버전)

풀이 방식

  • HashMap으로 각 숫자의 등장 횟수(빈도)를 센다.
  • Collections.max()로 가장 큰 빈도값을 구한다.
  • map을 돌며 최빈값 개수 확인
    1개면 그 숫자를 return
    여러 개면 -1 return
  • 최빈값이 여러 개 나오는 순간 바로 return -1로 빠르게 종료
import java.util.*;

class Solution {
    public int solution(int[] array) {
        Map<Integer, Integer> map = new HashMap<>(); // 각 숫자별 빈도 저장용

        for (int n : array)
            map.put(n, map.getOrDefault(n, 0) + 1); // 등장할 때마다 카운트 +1

        int max = Collections.max(map.values()); // 가장 큰 빈도값 구하기
        int mode = -1; // 최빈값
        int count = 0; // 최빈값 개수

        for (int key : map.keySet()) {
            if (map.get(key) == max) { // 해당 숫자의 빈도가 최댓값과 같으면
                mode = key; // 최빈값 후보
                count++;
                if (count > 1) return -1; // 두 개 이상이면 바로 -1 리턴
            }
        }

        return mode; // 최빈값 반환
    }
}

② 정석적인 풀이 (단계별로 명확히 나눈 버전)

풀이 방식

  • HashMap으로 빈도 계산
  • 1차: 최댓값(maxFreq) 구하기
  • 2차: 최빈값 후보들을 순회하며 개수 세기
  • 후보가 여러 개면 -1, 아니면 해당 값 반환
import java.util.*;

class Solution {
    public int solution(int[] array) {
        Map<Integer, Integer> freq = new HashMap<>(); // 숫자 → 빈도 저장

        for (int n : array)
            freq.put(n, freq.getOrDefault(n, 0) + 1); // 등장 횟수 누적

        int maxFreq = 0; // 최빈 빈도값
        for (int v : freq.values())
            maxFreq = Math.max(maxFreq, v); // 최대 빈도 갱신

        int mode = -1; // 최빈값
        int modeCount = 0; // 최빈값 개수

        for (int key : freq.keySet()) {
            if (freq.get(key) == maxFreq) { // 최빈값 후보라면
                mode = key;
                modeCount++;
            }
        }

        // 최빈값이 여러 개면 -1, 하나면 해당 값 반환
        return modeCount > 1 ? -1 : mode;
    }
}

③ Streams 버전 (자바 8 이상, 간결하지만 약간 무거움)

풀이 방식

  • Arrays.stream()으로 배열을 스트림으로 변환
  • Collectors.groupingBy()로 빈도 맵 생성
  • Collections.max()로 최댓값 찾기
  • filter()로 최빈값 후보만 걸러내서 리스트로
  • 여러 개면 -1, 하나면 반환
import java.util.*;
import java.util.stream.*;

class Solution {
    public int solution(int[] array) {
        // 배열 → Stream 변환 → 숫자별 등장 횟수 Map으로 변환
        Map<Integer, Long> freq = Arrays.stream(array)
            .boxed()
            .collect(Collectors.groupingBy(n -> n, Collectors.counting()));

        long max = Collections.max(freq.values()); // 최대 빈도 찾기

        // 최빈값 후보만 필터링해서 리스트로
        List<Integer> modes = freq.entrySet().stream()
            .filter(e -> e.getValue() == max)
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());

        // 후보가 여러 개면 -1, 아니면 첫 번째 값 반환
        return modes.size() > 1 ? -1 : modes.get(0);
    }
}

 

댓글