본문 바로가기
알고리즘/프로그래머스

[프로그래머스/파이썬] 레벨 0 최빈값 구하기

by Renechoi 2022. 10. 13.

[프로그래머스/파이썬] 레벨 0 최빈값 구하기

 

 

 

📌 문제 

최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다. 정수 배열 
array
가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요. 최빈값이 여러 개면 -1을 return 합니다.

 

 

⚔ 제한 사항

0 < array의 길이 < 100-1000 < array의 원소 < 1000

 

 

 

 

📣 입출력 예

 

[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입니다.

 

 

 


 

💡 나의 풀이

 

 

def solution(array):
    get_max_dict = dict(  (i, array.count(i)) for i in array )    ## 쌍으로 만들어서 딕셔너리 생성 	{1: 1, 2: 1, 3: 3, 4: 1} / {1: 2, 2: 2}

    ##딕셔너리 만드는 정석적인 방법    
#     dict = {}
#     for num in array : 
#         if not num in dict :
#             dict[num] = 1 
#         else :
#             dict[num] +=1 
            
    answer =0
    if len(get_max_dict) == 1 :                         # 딕셔너리의 키쌍이 한개이면 그 자체로 맥스값이 나올테니 바로 구해서 리턴 
        answer = list(get_max_dict.keys())[0]
    else :                                              # 1개가 아니면 중복인 것에 대해 처리해주어야 하므로 1번째 맥스와 2번째 맥스값을 비교해서 
        first_max = sorted(get_max_dict.values())[-1]
        second_max = sorted(get_max_dict.values())[-2]  
    
        if first_max == second_max :                    # 같으면 문제의 조건에 따라 -1 리턴 
            answer = -1
        else:         
            for key, value in get_max_dict.items() :    # values 값에 따라 매칭하는 key 값을 별도로 찾아서 리턴해주어야 함 
                if value == first_max :
                    answer = key
            
            
    
    return answer

 

 

두 가지 문제가 고민이었는데 

 

1) 최빈값을 어떤 방식으로 구해야 할지 

= 딕셔너리를 만들어서 구하는 방식으로 풀었다 

 

2) 구한 딕셔너리에서 중복을 어떻게 처리해야할지 

= 조건문으로 따져서 풀었다 

 

 

이렇게 풀고나면 영 찜찜한데 풀고 나서 다른 사람의 풀이를 찾아보았다. 

 

 

 

👀 다른 사람의 풀이 

def solution(array):
    while len(array) != 0:
        for i, a in enumerate(set(array)):
            array.remove(a)
        if i == 0: return a
    return -1

 

처음 문제를 받고 구상할때 while문을 돌릴까를 생각했었는데 역시나 그게 더 좋은 방법이 있었다. 

 

중복을 제거한 리스트에서 하나씩 지워가면서 0이 되면 반복문을 빠져나온다. 

 

그때 마지막으로 남아 있는 것이 가장 빈도수가 많은 key이다. 

 

이때 중복된 값에 대해서는 반복문 안에서 리턴하지 않기 때문에 while 조건에서 0을만나면서 자동으로 반복문이 끝나게 되고 

 

이것은 중복을 의미하기 때문에 바로 -1을 리턴시킨다 

 

 

참고로 enumerate 함수는 다음과 같이 인덱싱을 해주면서 반복문을 돌린다. 

for entry in enumerate(['A', 'B', 'C']):
   print(entry)



//(0, 'A')
//(1, 'B')
//(2, 'C')

 

정말 참신한 발상의 전환인듯 싶다. . . 

 

어떻게 이런 생각을 하지? 

 

 

 

반응형