
난이도: ★★☆☆☆ • solved on: 2026-01-17

자료구조
int[], HashMap<Integer,Integer>, ArrayList<Integer>int[] count (8001) 카운팅 배열알고리즘/기법
핵심 키워드
- 문제 분해
- 입력을 받으면서
min,max,total을 갱신한다.HashMap으로 각 수의 빈도를 센다.- 최빈값 후보를
ArrayList에 모은 뒤 정렬로 규칙(두 번째로 작은 값)을 맞춘다.arr를 정렬해 중앙값을 구한다.
핵심 로직 흐름
입력: min/max/total 갱신 map[num]++ map 순회: 최대 빈도 cnt 갱신 cnt와 같으면 후보 추가 cnt보다 크면 후보 초기화 후 추가 arr 정렬 -> 중앙값 후보 정렬 -> 최빈값 결정(두 번째로 작은 값)예외 처리
- 평균은
Math.round(1.0 * total / n)형태로 반올림한다.
import java.util.*;
import java.lang.*;
import java.io.*;
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 min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
int total = 0;
int freq = 4001;
int cnt = 0;
ArrayList<Integer> arrayList = new ArrayList<>();
HashMap<Integer,Integer> map = new HashMap<>();
int[] arr = new int[n];
map.put(freq, -1);
for(int i = 0; i < n; i++){
int temp = Integer.parseInt(br.readLine());
if(temp < min) min = temp;
if(temp > max) max = temp;
total += temp;
if(map.containsKey(temp)){
map.put(temp,map.get(temp)+1);
} else {
map.put(temp,1);
}
arr[i] = temp;
}
for(Integer key : map.keySet()){
if(map.get(key).equals(-1)){
continue;
}
if(map.get(key).equals(cnt)){
arrayList.add(key);
}
if(map.get(key).compareTo(cnt)>0){
arrayList.clear();
arrayList.add(key);
cnt = map.get(key);
}
}
Arrays.sort(arr);
arrayList.sort(Collections.reverseOrder());
System.out.println(Math.round(1.0 * total / n));
System.out.println(arr[n/2]);
if(arrayList.size() == 1){
System.out.println(arrayList.get(0));
} else {
System.out.println(arrayList.get(arrayList.size()-2));
}
System.out.println(max-min);
}
}
- 문제 분해
- 값 범위가
-4000 ~ 4000으로 고정이므로count[8001]로 빈도를 센다(인덱스는x + 4000).- 평균:
sum / n을Math.round로 반올림한다.- 중앙값: 누적 빈도가
(n+1)/2이상이 되는 지점을 찾는다(문제에서 N은 홀수).- 최빈값: 최대 빈도를 찾은 뒤, 오름차순 스캔 중 최빈값을 만나는 두 번째 값을 답으로 한다(동률 규칙 충족).
- 범위:
max - min을 출력한다.
핵심 로직 흐름
입력: sum, min, max 갱신 count[x+4000]++ median: 누적합 >= (n+1)/2 되는 최초 값 mode: maxFreq 구함 i=0..8000 오름차순으로 스캔하며 count[i]==maxFreq 인 값을 발견할 때마다 found++ found==1이면 mode=값 found==2이면 mode=값(두 번째로 작은 값)로 확정예외 처리
- 평균 반올림은 음수도 포함하므로
Math.round((double)sum / n)으로 처리한다.
import java.io.*;
class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] count = new int[8001]; // -4000~4000 => +4000 shift
long sum = 0;
int min = 4001;
int max = -4001;
for (int i = 0; i < n; i++) {
int x = Integer.parseInt(br.readLine());
sum += x;
if (x < min) min = x;
if (x > max) max = x;
count[x + 4000]++;
}
// 1) 산술평균
int mean = (int) Math.round((double) sum / n);
// 2) 중앙값 (N은 홀수)
int target = (n + 1) / 2;
int cumulative = 0;
int median = 0;
for (int i = 0; i < 8001; i++) {
cumulative += count[i];
if (cumulative >= target) {
median = i - 4000;
break;
}
}
// 3) 최빈값 (여러 개면 두 번째로 작은 값)
int maxFreq = 0;
for (int i = 0; i < 8001; i++) {
if (count[i] > maxFreq) maxFreq = count[i];
}
int mode = 0;
int found = 0;
for (int i = 0; i < 8001; i++) {
if (count[i] == maxFreq) {
mode = i - 4000;
found++;
if (found == 2) break; // 두 번째로 작은 최빈값 확정
}
}
// 4) 범위
int range = max - min;
StringBuilder sb = new StringBuilder();
sb.append(mean).append('\n');
sb.append(median).append('\n');
sb.append(mode).append('\n');
sb.append(range).append('\n');
System.out.print(sb);
}
}
방법 1
방법 2
HashMap을 저장하여 cnt를 확인했는데 나중 접근을 통해 카운팅 배열을 활용해볼 수 있다는 걸 확인했다. HashMap정렬보다 카운팅 배열이 구현도 단순하고 성능도 안정적이다.Math.round((double)sum / n)처럼 double로 변환해 처리하는 편이 명확하다.비슷한 유형 (GPT 추천):
확장 문제 (GPT 추천):