코딩 테스트 스터디/백준

[실버 IV] 2108번. 통계학

남쪽마을밤송이 2022. 2. 6. 01:18

 문제 

https://www.acmicpc.net/problem/2108

 

2108번: 통계학

첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.

www.acmicpc.net

 사용 언어 

Python3

 풀이 과정 

가장 문제가 되는 최빈값을 count함수를 사용해 풀었고 IDE에서는 정답이 출력되는 것을 확인했으나 백준에서는 시간 초과가 떴다. 찾아보니 count 함수는 시간복잡도가 O(n)인데 for문 안에다 써서 시간복잡도가 O(n^2)이나 된 것 같다...

출처: https://hyun-am-coding.tistory.com/entry/Python-list-%EC%97%B0%EC%82%B0%EC%97%90-%EB%94%B0%EB%A5%B8-%EC%8B%9C%EA%B0%84-%EB%B3%B5%EC%9E%A1%EB%8F%84

import sys
nums = []
count = int(sys.stdin.readline()) # 홀수만 입력
for _ in range(count):
  nums.append(int(sys.stdin.readline()))

nums.sort() # 오름차순 정렬
# 산술평균
print(round(sum(nums)/count))
# 중앙값
print(nums[int(count/2)])
# 최빈값
times = {}
all = list(set(nums)) # 중복제거한 리스트
for i in all:
  times[i] = nums.count(i) # 요소별 중복 횟수 딕테이션 생성
max_num = max(times.values())
result = []
for i in all:
  if times[i] == max_num: # 중복 횟수가 최대값이면
    result.append(i)
if len(result) == 1:
  print(result[0])
else:
  print(sorted(result)[1])
# 범위
print(nums[-1]-nums[0])

이걸 어떻게 고치지 고치지 하다가 검색을 해보고 딕셔너리는 counter 함수가 있다는 것이 기억나 수정했다.

쉽게 봤다가 힘들게 본 맞았습니다!!

 제출 답안 

import sys
from collections import Counter

nums = []
count = int(sys.stdin.readline()) # 홀수만 입력
for _ in range(count):
  nums.append(int(sys.stdin.readline()))
 
nums.sort() # 오름차순 정렬
# 산술평균
print(round(sum(nums)/count))
# 중앙값
print(nums[int(count/2)])
# 최빈값
times = Counter(nums)
max_count = times.most_common()
if len(max_count) > 1 and max_count[0][1] == max_count[1][1]: # 최빈값이 두 개 이상일 때
  print(max_count[1][0]) # 두 번째로 작은값 출력
else: # 모두 같은수일 때
  print(max_count[0][0])
# 범위
print(nums[-1]-nums[0])

 공부한 내용 

Counter

파이썬의 Counter 클래스는 iterable의 원소의 개수를 셀 때 편리하게 사용할 수 있는 기능으로, 딕셔너리 객체와 유사하다. 유니크한 원소의 이름들은 딕셔너리 key로, 각 원소의 카운트는 딕셔너리의 value로 저장된다.

Counter를 사용하기 위해서는 from collections import Counter를 호출해주어야 한다.

from collections import Counter

string_ex = 'aaaaabbbbbbccccccaaaaddddd'
c1 = Counter(string_ex)
c1 # Counter({'a': 9, 'b': 6, 'c': 6, 'd': 5})

list_ex = [1, 2, 3, 3, 3, 5, 2, 7]
c2 = Counter(list_ex)
c2 # Counter({1: 1, 2: 2, 3: 3, 5: 1, 7: 1})

- clear() : 카운터 객체에서 모든 key-value 쌍을 제거

- copy() : 카운터 객체의 복사본을 반환

- elements() : 카운터 숫자만큼 요소 반환, 리스트를 가지고 카운터 객체를 만들었다면, 다시 리스트로 돌린다고 생각하면 쉽다. 하지만 순서는 바뀐다. list(c2.elements())와 같이 사용.

- get() : 인자로 key를 입력하면 해당 key와 매칭되는 value를 반환

- items() : key, value 쌍을 튜플 형태로 반환

- keys() : 카운터 객체의 key들을 반환

- most_common() : 가장 빈도수가 높은 key, value 쌍부터 튜플 형태로 반환. 인자로 숫자(개수)를 전달하면 가장 빈도수가 높은 것부터 해당 개수만큼의 쌍만이 반환됨

- pop() : 인자로 key를 반드시 전달해야 하며, key와 매칭되는 value를 반환하고 해당 key, value 쌍을 카운터 객체에서 제거

- popitem() : 전달하는 인자가 없어야 하며, 가장 뒤의 key, value 쌍을 튜플 형태로 반환하고 해당 쌍을 카운터 객체에서 제거

- setdefault() : 카운터 객체에 key, value 쌍을 추가할 때 사용할 수 있음

     key만 전달하면 카운트 수는 디폴트로 None

     key와 함께 default=10과 같이 전달하면 key에 해당하는 카운트에 입력한 숫자가 반영됨

- subtract() : iterable을 전달하면 각 요소의 값을 각각 빼주고 그 결과의 카운트는 마이너스 값을 가질 수도 있음

- update() : iterable을 전달하여 같은 값이 있으면 카운트가 추가되게 하고 없으면 새로운 key, value 쌍을 생성

- values() : 카운터 객체의 value, 즉 카운트들을 반환

이 외에 더하기, 빼기, 교집합, 합집합 연산도 가능하고 카운트가 양수인 요소만 반환하거나 음수인 요소만 반환할 수도 있다. 

 

출처: https://ek-koh.github.io/python/counter/https://www.byfuls.com/programming/read?id=30