TIL 38 | 통계학 (백준 2108 python)

Gom·2021년 3월 16일
0

Algorithm

목록 보기
15/48
post-thumbnail

문제 바로가기

접근방식

요구하는 기능들 대체로 간단하지만 최빈값의 조건이 조금 까다롭다.
최빈값이 여럿일 때 최빈값 중 두번째로 작은 값을 출력해야했다.
함수를 사용하지 않고 푼 버전(그러나 시간초과..)과 함수를 사용하여 정답으로 인정된 코드를 첨부한다.

정답코드

import sys

from collections import Counter

r=sys.stdin.readline

n=int(r())
num_list =[]

for _ in range(n):
    num = int(r())
    num_list.append(num)

num_list.sort()

mode = Counter(num_list).most_common(2) 

print(round(sum(num_list)/len(num_list)))
print(num_list[len(num_list)//2])
print(mode[1][0] if len(mode)>1 and mode[0][1]==mode[1][1] else mode[0][0])
print(num_list[-1]-num_list[0])

시간초과 코드

import sys
r=sys.stdin.readline

n=int(r())
num_list =[]
for _ in range(n):
    num = int(r())
    num_list.append(num)

num_list.sort()

# 각 숫자별 사용빈도를 딕셔너리에 저장
cnt=dict()
for num in set(num_list):
    cnt[num]=num_list.count(num)

# 최빈값들을 찾아내어 리스트에 저장
mode = [
for key, value in cnt.items():
    if value == max(cnt.values()):
        mode.append(key)

mode.sort()

print(round(sum(num_list)/len(num_list)))
print(num_list[len(num_list)//2])
print(mode[0] if len(mode)==1 else mode[1])
print(num_list[-1]-num_list[0])

해결 과정 및 알게된 것

  1. sort와 sorted의 차이는 sort는 리스트 자체를 변경, sorted는 새 객체를 생성한다는 것이다. 해당 문제에서는 원래의 리스트 순서 자체를 변경하여 여러 계산식에 활용해야 하므로 sort함수를 이용하였다.

  2. 최빈값을 딕셔너리안에 저장시키려고 했다. 람다식을 이용하여도 되지만 밸류값을 이용하여 정렬하는 것은 효율이 떨어진다고 하여 애초에 키값에 빈도수를, 밸류에는 해당 숫자를 입력하여 저장하려했다. 그러나 딕셔너리는 키가 중복되면 가장 최근 값으로 덮어씌워진다는 특징때문에 사용할 수 없었다. (빈도수를 키에 저장한다면 빈도수가 동일한 숫자가 있을 경우 병합되는 문제 발생)

  3. 까다로웠던 부분은 최빈값이 여러 개 있을 때 최빈값 중 두 번째로 작은 수를 출력 해야 하는 것이었다. 빈도수가 동일한 수가 몇 개나 될 지 모르기에 인덱스를 이용해 두번째로 작은 값을 찾아내기는 어려워 보였다. 딕셔너리에 숫자별 빈도수 저장 후 max 빈도수 값을 가진 숫자들을 새로운 리스트에 저장하여 오름차순 정렬, 리스트의 길이가 1을 초과한다면 앞에서 두번째에 있는 값을 출력하면 될 일이었다.

  4. 3번 방식대로 구현하고 나니 시간초과가 났다. 더 효율적인 코드로 개선해야한다.

    4-1. 개선방안을 찾는 과정에서 파이썬 collections의 Counter 모듈을 사용하면 최빈값을 즉시 찾아낼 수 있다는 것을 알아냈다. Counter()는 빈도수를 dict로 만들고 most_common()은 배열안에 튜플 형식으로 최빈값을 반환한다. 언어 의존도가 높은 방식을 택하고 싶지 않았지만 10줄 정도의 코드를 한 줄로 압축시키는 위력과 성능 향상(2초 이상 → 508ms) 에 못 이기는 척 넘어가기로 했다. 시간초과 코드를 통해 원리를 이해하고 구현할 수 있게 된 것으로 일단 만족하기로 했다. 남은 알고리즘 문제가 많다.

profile
안 되는 이유보다 가능한 방법을 찾을래요

0개의 댓글