본문 바로가기

코딩테스트

[JAVA] 백준 2108 - 통계학

728x90

 

 

 

🤔 문제 접근

구현 문제인 통계학 문제이다.

어려운 문제는 아니었지만 산술 평균쪽과 최빈값 계산에 있어서 살짝 헤맸다.

 

산술 평균을 구할 때 데이터 형식을 int로 하여 계산할 경우

예를 들어 전체 합 / N 의 값이 -1.8일 때 -1로 나올 수 있다.

따라서 double 형으로 계산하고 Math.round 메소드를 통해 소수 첫째자리에서 반올림 한 뒤

int 형으로 변환하여 값을 반환해주자.

 

또한 최빈값을 구하는 과정은 각 숫자들을 map에 집어넣고

가장 많이 나온 횟수인 maxCount를 구한 뒤, key의 value가 maxCount와 같은 key들을

찾아내도록 했다. 이때 key의 개수가 2개 이상이라면 두번째로 작은 값을 반환해주었다.

key들을 구하고 다시 key들을 순회하며 2번째로 작은 값을 구하는 것 보다는

처음에 map에 넣을 때 정렬한 상태로 넣으면 이후 key 개수가 2개 이상일 때

바로 앞에서 2번째 값을 반환하면 되므로 TreeMap을 사용해서 map에 put 할 때

정렬되도록 했다.

 

🚨CODE

import java.io.*;
import java.util.*;

/*
 * 산술평균 : 그냥 합을 구하면 된다
 * 중앙값 : 정렬 필요, 시간초과는 안날거같음
 * 최빈값 : 가장 많이 나타나는 값, 데이터를 입력 받으며 세주면 될듯?
 * 범위 : 정렬 필요, 중앙값을 구하며 같이 구하면 될듯
 */

public class Main {
	public static void main(String[] args) throws Exception  {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int n = Integer.parseInt(br.readLine());
		ArrayList<Integer> numbers = new ArrayList<>();
		for(int i = 0; i<n; i++) {
			int number = Integer.parseInt(br.readLine());
			numbers.add(number);
		}
		StringBuilder sb = new StringBuilder();
		Collections.sort(numbers);
		
		sb.append(avg(numbers)).append("\n");
		sb.append(mid(numbers)).append("\n");
		sb.append(frequency(numbers)).append("\n");
		sb.append(range(numbers)).append("\n");
		System.out.println(sb);
	}
	public static int avg(ArrayList<Integer> numbers) {
		double sum = 0;
		for(double number : numbers) {
			sum += number;
		}
		double avg = sum/numbers.size();
		return (int) Math.round(avg);
	}
	public static int mid(ArrayList<Integer> numbers) {
		return numbers.get((numbers.size()-1)/2);
	}
	public static int frequency(ArrayList<Integer> numbers) {
		// 최빈값, 가장 많이 나온 값, 여러개면 두번째로 작은 값을 구한다.
		Map<Integer,Integer> map = new TreeMap<>();
		int maxCount = 0;
		for(int number : numbers) {
			map.put(number, map.getOrDefault(number, 0)+1);
			int count = map.get(number);
			if(count > maxCount)
				maxCount = count;
		}
		Queue<Integer> q = new LinkedList<>();
		for(int key :map.keySet()) {
			if(map.get(key) == maxCount)
				q.add(key);
		}
		
		if(q.size() > 1) {
			q.poll();
			return q.poll();
		}else {
			return q.poll();
		}
			
	}
	public static int range(ArrayList<Integer> numbers) {
		return Collections.max(numbers) - Collections.min(numbers);
	}
}
728x90
반응형