코딩 테스트

[프로그래머스] 최빈값 구하기 - JAVA

juble 2024. 11. 24. 16:45

문제 설명

최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다. 정수 배열 array가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요. 최빈값이 여러 개면 -1을 return 합니다.

 

제한사항

0 < array의 길이 < 100
0 ≤ array의 원소 < 1000


입출력 예

array  result
[1, 2, 3, 3, 3, 4] 3
[1, 1, 2, 2]  -1
[1] 1



입출력 예 설명

  • 입출력 예 #1 
    • [1, 2, 3, 3, 3, 4]에서 1은 1개 2는 1개 3은 3개 4는 1개로 최빈값은 3입니다.
  • 입출력 예 #2
    • [1, 1, 2, 2]에서 1은 2개 2는 2개로 최빈값이 1, 2입니다. 최빈값이 여러 개이므로 -1을 return 합니다.
  • 입출력 예 #3
    • [1]에는 1만 있으므로 최빈값은 1입니다.
반응형

풀이 1 - entrySet()을 순회하여 최빈값 확인

import java.util.*;

class Solution {
    public int solution(int[] array) {
        // Map을 사용해 빈도수 계산
        Map<Integer, Integer> frequencyMap = new HashMap<>();
        
         // 배열의 각 원소 카운트
        for (int num : array) {
            frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
        }
        
        // 최빈값과 빈도값 추적
        int maxFrequency = 0;
        int mode = -1;
        boolean multipleModes = false;

        for (Map.Entry<Integer, Integer> entry : frequencyMap.entrySet()) {
            int key = entry.getKey();
            int frequency = entry.getValue();

            if (frequency > maxFrequency) {
                maxFrequency = frequency;
                mode = key;
                multipleModes = false; // 새로운 최빈값이 나오면 단일 모드로 설정
            } else if (frequency == maxFrequency) {
                multipleModes = true; // 동일한 빈도값이 있으면 multipleModes를 true로 설정
            }
        }
        
        // 최빈값이 여러 개인 경우 -1 반환
        return multipleModes ? -1 : mode;
    }
}
  1. 빈도수 맵 생성:
    • Map<Integer, Integer>를 사용하여 각 숫자의 빈도를 저장합니다.
    • num의 빈도는 frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1)로 계산합니다.
  2. 최빈값 탐색:
    • Map.Entry로 빈도와 키를 하나씩 확인하여 최대 빈도를 찾습니다.
    • frequency > maxFrequency인 경우 최빈값을 갱신하고, frequency == maxFrequency인 경우 최빈값이 여러 개임을 확인합니다.
  3. 결과 반환:
    • 최빈값이 여러 개인 경우 multipleModes가 true가 되어 -1을 반환합니다.
    • 단일 최빈값이라면 mode를 반환합니다.

특징:

  • 명확한 로직 분리:
    빈도를 계산하는 부분과 최빈값을 찾는 부분이 분리되어 가독성이 좋습니다.
  • 두 번의 순회:
    배열을 순회하며 빈도를 계산한 뒤, 맵을 순회하여 최빈값을 찾습니다.

장점:

  • 코드가 직관적이며, 중복 계산 없이 명확하게 작성되었습니다.
  • Map.Entry를 사용하여 key와 value를 명시적으로 다룹니다.

풀이 2 - 배열 순회 중 실시간으로 최빈값 확인

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;
    }
}
  1. 맵을 사용하여 빈도 계산:
    • Map<Integer, Integer>로 각 숫자의 빈도를 계산합니다.
    • count = map.getOrDefault(number, 0) + 1로 해당 숫자의 빈도를 갱신합니다.
  2. 최빈값 실시간 갱신:
    • 숫자의 빈도를 계산하면서 즉시 maxCount와 비교하여 최빈값(answer)을 갱신합니다.
    • count > maxCount이면 새로운 최빈값을 갱신하고, count == maxCount인 경우 최빈값을 -1로 설정합니다.
  3. 결과 반환:
    • 최빈값을 실시간으로 갱신하므로 추가적인 맵 순회 없이 결과를 반환합니다.

특징:

  • 한 번의 순회:
    배열을 순회하면서 동시에 빈도를 계산하고 최빈값을 확인합니다.
  • 단순화된 로직:
    최빈값 확인과 갱신을 배열 순회 중에 실시간으로 처리합니다.

장점:

  • 한 번의 루프로 모든 작업을 처리하여 효율적입니다.
  • 별도의 중복 확인 플래그(multipleModes)를 사용하지 않아 간결합니다.
728x90

✅ getOrDefault

Java의 Map 인터페이스에서 제공하는 메서드로, 특정 키에 대한 값을 가져오되, 해당 키가 맵에 존재하지 않으면 기본값을 반환하는 기능을 제공

V getOrDefault(Object key, V defaultValue)

 

  • key: 값을 가져오려는 키.
  • defaultValue: 맵에 해당 키가 없을 때 반환할 기본값.

✅ Map.Entry 와 countMap.entrySet()

  1. Map.Entry란?
    • Map.Entry는 Map 인터페이스에서 내부적으로 사용되는 키-값 쌍 (Key-Value Pair)을 표현하는 객체
    • 즉, Map의 각 요소(키와 값의 한 쌍)를 다룰 때 사용하는 데이터 구조
    • Map.Entry와 관련된 주요 메서드
      • getKey():
        현재 Map.Entry의 키를 반환
      • getValue():
        현재 Map.Entry의 값을 반환
      • setValue(V value):
        현재 키에 새로운 값을 설정 (잘 사용되진 않음)
  2. entrySet() 메서드
    • entrySet()은 Map에서 모든 키-값 쌍을 Set 형태로 반환하는 메서드
    • 반환된 Set의 각 요소는 Map.Entry 객체

 

728x90
반응형