2 분 소요



https://www.acmicpc.net/problem/2108



🔍 문제 풀이

Collections.max(map.values())

Collections.max(map.values())컬렉션(이 문제에서는 map의 value들 중) 에서 가장 큰 값을 찾는 메서드이다.

  • map.values()
    • → Map에 저장된 모든 값(value) 들을 가져온다.
    • e.g., {1=2, 2=3, 3=3}이면 map.values()는 `[2, 3, 3].


  • Collections.max(...)
    • → 주어진 값들 중 최댓값을 리턴한다.


map이 아래와 같다고 할 때:

{10=2, 20=3, 30=1, 40=3}

→ 각 숫자(10, 20, 30, 40)가 나온 횟수(빈도)를 저장한 것
→ 가장 많이 나온 횟수(최빈값의 빈도수)는 3

이를 얻기 위해 사용하는 게 Collections.max(map.values())


그럼 최빈 값이 여러 개일 경우 어떻게 하지?

여러 개일 수 있으니 리스트에 담고 정렬 후 조건 처리한다.

int maxFreq = Collections.max(map.values());
List<Integer> modeList = new ArrayList<>();

for (int key : map.keySet()) {
    if (map.get(key) == maxFreq) {
        modeList.add(key);
    }
}

Collections.sort(modeList); // 오름차순 정렬
int mode = modeList.size() >= 2 ? modeList.get(1) : modeList.get(0); // 두 번째로 작은 값


entrySet()과 Map.Entry

코드 의미
Map.Entry<K, V> Map의 key-value 한 쌍을 표현하는 객체
map.entrySet() Map 안의 모든 entry(key, value)를 Set으로 반환
entry.getKey() 해당 쌍의 key
entry.getValue() 해당 쌍의 value


entrySet()

  • entrySet()Map에 저장된 (key, value) 쌍 전체를 Set 형태로 반환한다.
  • 즉, Map을 반복문으로 순회할 때 사용하는 대표적인 방식이다.
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
    int key = entry.getKey();
    int value = entry.getValue();
    // key: 숫자, value: 등장 횟수
}


왜 사용할까?

최빈값을 구하기 위해선 모든 (숫자, 횟수) 쌍을 하나씩 검사해야 한다.

이때 entrySet()을 사용하면 key와 value를 동시에 쉽게 꺼낼 수 있다.

// value가 maxFreq인 key들만 리스트에 모으기
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
    if (entry.getValue() == maxFreq) {
        modes.add(entry.getKey());
    }
}



💻 전체 코드

import com.sun.jdi.Value;

import java.io.*;
import java.security.Key;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int n = Integer.parseInt(br.readLine());
        int[] arr = new int[n];

        double sum = 0;

        Map<Integer, Integer> map = new HashMap<>();
        for(int i=0; i<n; i++){
            int x = Integer.parseInt(br.readLine());
            arr[i] = x;
            sum += x;
            map.put(x, map.getOrDefault(x , 0) + 1);
        }
        Arrays.sort(arr);

        // 산술 평균
        System.out.println(Math.round(sum/n));

        // 중앙값
        System.out.println(arr[n/2]);

        // 최빈값
        int frequencyNum = Collections.max(map.values());

        List<Integer> frequencyList = new ArrayList<>();


        // 방법1) map.entrySet()
        for(Map.Entry<Integer, Integer> entry: map.entrySet()){
            if(entry.getValue() == frequencyNum){
                frequencyList.add(entry.getKey());
            }
        }
s
        // 방법2) map.keySet()
        for (int key : map.keySet()) {
            if (map.get(key) == frequencyNum) {
                frequencyList.add(key);
            }
        }

        Collections.sort(frequencyList);

        if(frequencyList.size() > 1){
            System.out.println(frequencyList.get(1));
        }else{
            System.out.println(frequencyList.get(0));
        }


        // 범위
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for(int i=0; i<n; i++){
            max = Math.max(max, arr[i]);
            min = Math.min(min, arr[i]);
        }
        System.out.println(max - min);
    }
}



💭 배운 점

  • 최빈값을 구할 때 단순히 Map에서 찾는 것만으로는 부족하고,
    최빈값 후보들을 List에 모아 정렬한 후 두 번째로 작은 값을 출력해야 한다.
  • Map.EntryentrySet()을 통해 (key, value) 쌍을 순회할 수 있다.
  • Math.round()를 쓰면 산술평균을 정확하게 반올림할 수 있다.


카테고리:

업데이트:

댓글남기기