https://www.acmicpc.net/problem/2108
처음 풀이
import sys
from collections import Counter
n = int(sys.stdin.readline())
numbers = []
for _ in range(n):
numbers.append(int(sys.stdin.readline()))
# 산술평균
print(round(sum(numbers) / n))
# 중앙값
numbers.sort()
print(numbers[n // 2])
# 최빈값
cnt = Counter(numbers).most_common()
print(cnt)
if len(cnt) > 1 and cnt[0][1] == cnt[1][1]:
print(cnt[1][0])
else:
print(cnt[0][0])
# 범위: (최댓값-최솟값)
print(max(numbers) - min(numbers))
- 서치 해서 알아낸 것이다. 최빈값을 구할 때 Counter의 most_common() 메서드를 사용하면 최빈값이 큰 순으로 dictionary 형태로 정렬이 된다. 그리고 키값이 작은 순으로 정렬이 되기 때문에 문제 조건인 두 번째로 작은 값을 찾아낼 수 있다.
- 이를 통해서 길이가 1이 넘고 빈도수가 같으면 뒤의 수의 키값을 출력한다.
https://st-lab.tistory.com/108
이분의 풀이를 해석하면서 파이썬으로 구성하였다.
import sys
n = int(sys.stdin.readline())
numbers = []
numbers_frequency = [0] * 8001
for _ in range(n):
number = int(sys.stdin.readline())
numbers_frequency[number + 4000] += 1
numbers.append(number)
median = 0
count = 0
mode = 0
mode_max = 0
flag = False
for i in range(min(numbers) + 4000, max(numbers) + 4001):
if numbers_frequency[i] > 0:
if count < int((n + 1) / 2):
median = i - 4000
count += numbers_frequency[i]
if mode_max < numbers_frequency[i]:
mode_max = numbers_frequency[i]
mode = i - 4000
flag = True
elif mode_max == numbers_frequency[i] and flag:
mode = i - 4000
flag = False
# 산술 평균. 소수점 이하 첫째 자리에서 반올림한 값을 출력
print(round(sum(numbers) / len(numbers)))
# 중앙값
print(median)
# 최빈값
print(mode)
# 범위 출력
print(max(numbers) - min(numbers))
- 정렬을 하지 않고 counting 정렬을 통해 빈도수를 계산해 냈다.
- for문을 통해 최솟값 + 4000, 최댓값 + 4001의 범위를 인덱스로 사용한다.
- 빈도수가 0 초과일 때 조건문에 들어간다.
- 중앙값을 구할 때는 n이 홀수라 했으니 1을 더한 뒤 2로 나눈 인덱스보다 빈도수의 누적 값이 같거나 커지면 그 값이 중앙값인 것이다. (첫 번째 if문)
- 만약 최빈값만 구하는 문제라면 쉬웠겠지만 그게 아니라 최빈값이 여러 개면 두 번째로 작은 값을 구하는 것이기 때문에 flag라는 boolean 값을 이용해서 문제를 풀어야 한다.
- 3,3,3, 4,4,4, 5,5,5, 7,7,7이라고 가정하자
- 처음 (키값 3 , 빈도수 3)인 값이 넘어온다 -> mode_max(default 0) < numbers_numbers_frequency [i]를 무조건 만족한다.
- 값이 각각 저장되고 flag = True가 된다.
- 만약 이전 값과 다음 값(4, 3)의 빈도수가 같다면 elif의 첫 번째 조건은 만족하는 셈. 여기서 flag=True기 때문에 조건에 충족한다.
- 최빈값이 바뀌게 되며(이전 빈도수와 현재 빈도수가 같으므로) flag=False로 문을 닫아준다(이게 핵심)
- (5, 3)이 넘어온다. 두 번째 elif문으로 넘어온다. 첫 번째 조건은 만족하나 flag가 False이므로 조건문을 통과하지 못한다.
- 최빈값의 답은 4가 출력이 되게 된다.
- 이후에 8이 4번 나왔다면 첫 번째 if문을 통해 최빈값이 바뀐다.
- 뭔가 어려워 보였는데 그림으로 그려보니 이해가 되었었다.
'자료구조 & 알고리즘 관련 > 코딩테스트' 카테고리의 다른 글
수열 정렬 (0) | 2023.01.29 |
---|---|
유기농 배추 (0) | 2023.01.29 |
소트인사이드 (0) | 2023.01.28 |
콜라 문제 (0) | 2023.01.27 |
Design Browser History (0) | 2023.01.26 |