Algorithm/Sorting

[백준 2108번] 통계학

킹우현 2023. 2. 24. 17:45

import sys
input = sys.stdin.readline

# n 입력받기
n = int(input())

# n개의 값을 저장하는 리스트
array = [0]*n
# 빈도수를 저장하는 리스트
count_list = []

# 최빈값
mode = 0

# 입력받기
for i in range(n):
  array[i] = int(input())

# 중간 인덱스
mid_index = n//2

# 오름차순 정렬
array.sort()

# 집합 자료형 사용
set_n = set(array)
# 사전 자료형 사용
dictionary = dict()

# 사전 자료형에 숫자 '값 : 빈도수(카운팅)' 저장 => 시간복잡도 최소화
for i in array:
  if i not in dictionary:
    dictionary[i] = 1
  else:
    dictionary[i] += 1

# 빈도수 리스트에 튜플(값, 빈도수)로 저장
for i in set_n:
  count_list.append((i, dictionary[i]))

# 먼저 값의 내림차순으로 정렬(추후에 2번째로 작은 값을 구하기 위해)
count_list.sort(key=lambda x:-x[0])
# 빈도수를 기준으로 오름차순 정렬(최빈값을 찾기위해)
count_list.sort(key=lambda x:x[1])

count_c = len(count_list)

# 최빈 값이 같은 것이 여러 개 경우에 2번째로 작은 값을 최빈값으로 설정
if count_list[count_c-1][1] == count_list[count_c-2][1]:
  mode = count_list[count_c-2][0]
# 최빈 값이 유일한 경우엔 그대로 반환
else:
  mode = count_list[count_c-1][0]

print(round(sum(array)/n)) # 산술평균
print(array[mid_index]) # 중앙값
print(mode) # 최빈값
print(array[n-1]-array[0]) # 범위

이번 문제는 n개의 수가 주어졌을 때, 이 수들의 산술평균, 중앙값, 최빈값, 범위(최대값-최소값)을 구하는 문제이다.

 

산술평균은 단순히 sum() 함수를 사용하고 n으로 나눈 후 round()함수로 반올림해주면 간단하게 풀 수 있고, 중앙값과 범위 또한 정렬 라이브러리를 사용하면 쉽게 정렬할 수 있었다.

 

하지만 이 문제의 관건은 바로 "최빈값"을 구하는 것이다.

 

처음에는 뭔가 시간복잡도 때문에 틀릴 것을 감지하고 있었지만, 한번 테스트삼아 count()함수를 사용하여 풀었더니 당연하게도 시간 초과가 발생하였다.

 

따라서 이전에 문제에서 배웠던 사전 자료형(Dictionary)를 사용하여 값의 빈도수를 저장하고, 최빈 값을 찾는 방식으로 풀었더니 정답을 맞힐 수 있었다 :)