[백준] 2108-통계학-Java
[백준] 2108-통계학-Java
❓문제
N개의 정수를 입력 받아 아래의 값을 하나씩 출력하라.
- 산술평균 : N개의 수들의 합을 N으로 나눈 값
- 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
- 최빈값 : N개의 수들 중 가장 많이 나타나는 값
- 범위 : N개의 수들 중 최댓값과 최솟값의 차이
- 최빈값이 여러 개 인 경우 최빈값 중 두번째로 작은 값을 출력한다.
- 정수의 절대값은 4,000을 넘지 않으며 N의 범위는 1 ≤ N ≤ 500,000 이다.
🖊️풀이법
이번 문제는 최빈값을 제외하고는 간단하게 풀 수 있다.
정수이 절대 값이 4,000을 넘지 않기때문에 카운트정렬을 이용하면 보다 빠르게 풀 수 있다.
절대 값 4000을 기준으로 음수범위, 양수범위를 표현해줄 크기가 8001인 int 배열 arr를 초기화 해준다.
- 산술평균
변수 sum
을 선언하여, 정수를 입력 받을 때마다 더하고, 더한 값을 N으로 나눠 출력한다.
단, 출력 시 반올림 하여 출력해야하기 때문에 double형
으로 나눈 후 Math.round
를 통해 반올림 후 int
타입으로 형 변환을 시켜준다.
- 중앙값
반복문을 순회하며, arr[i]
가 0이 아닐 경우 해당 값을 count에 더해주고 중앙값에 i-4000
을 담아준다.
count
가 (N+1)/2
보다 작을 때 까지 순회하고, 만약 (N+1)/2
보다 커지면 if문
을 실행시키지 않고 해당 median값
을 반환한다.
- 최빈값
max값을 구하는 로직을 만들어 arr[i]
의 배열이 max
인 경우, mode(최빈 값)
를 i-4000
로 할당해줌과 동시에 최빈 값이 동일할 경우를 대비해 flag
를 true
로 변환해 준다.
만약 mode_max
의 값이 같고 flag
가 true
인 경우, 최빈 값을 다시 재지정 후 flag
를 false
로 변환한다.
최빈값이 여러개인 경우 두번째 작은 수를 반환해야하기 때문
정답 코드
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(br.readLine());
int[] arr = new int[8001];
int sum = 0;
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
int median = 0;
int mode = 0;
for(int i = 0; i< N; i++){
int num = Integer.parseInt(br.readLine());
arr[num+4000]++;
sum += num;
if(num > max){
max = num;
}
if(num < min){
min = num;
}
}
int count = 0;
int mode_max = 0;
boolean flag = false;
for(int i = min + 4000; i<= max+4000; i++){
if(arr[i] > 0){
//최빈값 구하기
if(count < (N+1) /2){
count += arr[i];
median = i - 4000;
}
//최빈값 구하기
if(mode_max < arr[i]){
mode_max = arr[i];
mode = i - 4000;
flag = true;
} else if(mode_max == arr[i] && flag){
mode = i - 4000;
flag = false;
}
}
}
int average = (int)Math.round((double)sum/N);
int range = max-min;
sb.append(average).append('\n')
.append(median).append('\n')
.append(mode).append('\n')
.append(range).append('\n');
System.out.println(sb);
}
}
정리
풀이법만 봐서는 이해가 잘 가지않을 수 있기 때문에, 반드시 코드와 함께 보는 것을 권장한다.
이번 문제는 최빈값이 여러개인 경우, 두 번째로 작은 숫자를 출력하는 부분이 핵심인 것 같다.
boolean
타입으로 상태표시를 처리해 줌으로써 풀 수 있는 문제였다.