[Python 코딩테스트] 최빈값 구하기
최빈값 구하기 문제 풀이중 꽤나 고민했던 부분이 있어서 해결과정을 작성한다.
문제
- 최빈값 구하기
최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다. 정수 배열 array가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요. 최빈값이 여러 개면 -1을 return 합니다.
제한사항
- 0 < array의 길이 < 100
- 0 ≤ array의 원소 < 1000
입출력 예arrayresult
[1, 2, 3, 3, 3, 4] | 3 |
[1, 1, 2, 2] | -1 |
[1] | 1 |
입출력 예 설명
입출력 예 #1
- [1, 2, 3, 3, 3, 4]에서 1은 1개 2는 1개 3은 3개 4는 1개로 최빈값은 3입니다.
입출력 예 #2
- [1, 1, 2, 2]에서 1은 2개 2는 2개로 최빈값이 1, 2입니다. 최빈값이 여러 개이므로 -1을 return 합니다.
입출력 예 #3
- [1]에는 1만 있으므로 최빈값은 1입니다.
위 처럼 문제가 주어졌고, 그닥 어려운 문제는 아니라고 생각한다.
하지만 최빈값이 여러개일때 -1을 리턴하는 부분에서 어떻게 하면 쉽고 효율적으로 체크할수 있을까라는 생각에 고민했던 시간이있다.
최초작성 코드
def solution(array):
cnt = {} #(1)
for v in array:
if cnt.get(v) is None:
cnt[v] = 0
cnt[v] += 1
items = sorted(cnt.items(), key = lambda i: i[1], reverse = True) #(2)
answer = -1 if len(items) > 1 and items[0][1] == items[1][1] else items[0][0] #(3)
return answer
코드 작성을 나눠서 보면
(1) : dict 를 하나 만들고, array를 한번씩 돌면서 값으로 key를 생성하면서 해당 카운트를 1씩 올려준다.
(2) : dict.items() 로 (key, value) 리스트로 value 기준으로 오름차순 정렬한다.
(3) : items 이 1이상이면 index 0과 1의 value 를 비교해 최빈값이 여러개인지 아닌지 판단하여 answer 값을 리턴한다.
위 코드로 채점은 통과했지만, 뭔가 최빈값이 여러개인지 체크하는 부분의 코드가 아쉬웠다. 좀더 괜찮은 방법에 대해 고민해서 다른방식으로 생각했다.
다른방식 소거 방식
아래 방법은 총 array 에서 중복제거한 set 에서 array 에 속한 값을 하나씩 제거 하는방법이다.
이렇게 하면 가장 중복이 많은 값은 다른 값보다 하나 이상 계속 남아 잇을것이다.
마지막에 남은 값이 최빈값으로 리턴할수 있게 된다.
소거 방식 코드
def solution(array):
# array 항목이 남아있다면 반복
while len(array) > 0:
for i, v in enumerate(set(array)):
# 중복제거후 array에서 하나씩 뺀다.
array.remove(v)
# 위 for 돌았는데도 i == 0 이면 하나 남았다는 의미로 v 리턴
if i == 0: return v
# 다 빠졌으면 최빈값이 두개 이상이므로 -1
return -1
더 효율적인 방법인지는 모르겠지만, 최빈값이 여러개인지 체크하는 부분에 있어서 좀더 신경을 안써도 되는 방식이라 이런 사고방식도 알아두는게 좋을 것이라 생각한다.