본문 바로가기
알고리즘 풀이

[algorithm] 프로그래머스: 최빈값 구하기

by 째깍단 2023. 4. 5.

답: 

더보기
def solution(array):
    num_dict = {}
    for num in array:
        if num in num_dict:
            num_dict[num] += 1
        else:
            num_dict[num] = 1

    # 내림차순 정리를 한다
    sorted_list = sorted(num_dict.items(), reverse=True, key=lambda item: item[1])

    # 1, 2번째 값의 value값을 비교하여 1이크면 key값, 같으면 -1, 배열이1개면 key값 반환    
    answer = 0

    if len(sorted_list) == 1:  # key-value값이 하나만 존재하는 경우
        answer = sorted_list[0][0]
        return print(answer)

    elif sorted_list[0][1] > sorted_list[1][1]:  # answer는 value값에 해당하는 key값
        answer = sorted_list[0][0]
        return print(answer)

    else:
        sorted_list[0][1] = sorted_list[1][1]
        answer = -1
        return print(answer)

 

문제:

  배열 값중 가장 많이 나온 것을 출력

  2개이상이면 -1 출력

  값이 1개인 배열이면 그 숫자 출력

 

 

문제 분석 및 해석

"""

- 일단 숫자를 세어 dict로 뽑아내보자

 

방법1. collections 라이브러리의 counter

counter는 가장 값이 높은 것부터 차례로, 사전형태로 정리해준다. 

 

방법2. for in 으로 각 요소 숫자 세어주기

어제 이 방법으로 하여 잘 정리된 dict를 얻었다.

 

 

-------------------------------------------

 

- dict에서 최빈값 찾기

 

방법 1. value에서 가장 큰 값을 찾고,

value끼리 비교한다음 key값을 불러온다..

 

>> 어제해본 방법이지만 너무 복잡해져서 스스로 어떤 내용인지,

적절한 위치에 두었는지 알 수 없었다. 문제가 많은 코드가 탄생함

 

 

그래서 추천받은 방법2.

value값을 sort로 오름/내림차순 정리를 한 다음 

가장 큰 값과 바로 그 전값을 비교해 key값을 출력한다

 

>> 이걸로 도전해봤다.

 

정보조사:

# value 값을 기준으로 오름차순 정렬하여 key-value가 튜플로 묶인 리스트 반환
print(sorted(my_dict.items(), key=lambda x:x[1]))

# 위 값을 딕셔너리로 변환
print(dict(sorted(my_dict.items(), key=lambda x:x[1])))

"""

 

 

 

 

과정 1)  일단 배열을 dict로 정리해주는 함수 작성

 

빈 dict를 만들고, for문으로 배열을 검사하여 해당 dict에 요소가 없으면 key-value값을 추가

있으면 +1을 하여 숫자를 셀 수 있도록 하였다.

def solution(array):
    num_dict = {}
    for num in array:
        if num in num_dict:
            num_dict[num] += 1
        else:
            num_dict[num] = 1

 

 

과정 2)  내림차순으로 정리한다.

# 내림차순 정리를 한다
sorted_list = sorted(num_dict.items(), reverse=True,key=lambda item: item[1])

print(sorted_list)
#결과 [(3,3),(2,1),(1,1),(4,1)]

sorted함수를 사용하면 리스트로 묶인 튜플이 튀어나온다.

reverse를 true값으로 해주었기 때문에 내림차순으로 정리되었다.

 

 

 

 

과정 3)  각각의 value를 꺼내어 비교하고,  출력값을 반환한다.

 

***이때 튜플의 1, 2번 value값만 비교하면 겹치는 값이 있는지 확인할 수 있다.

 

일단 반환할 answer에 0을 주고   sorted_list 의 내용물을 검사하고자 했다.

 

 

#처참..
for v in sorted_list:
    if v[0][1] > v[1][1]:  
        answer = sorted_list[0][1]
        return answer
    else:
        v[0] = v[1]
        answer = -1
        return answer

이 코드를 돌리면 TypeError: 'int' object is not subscriptable 이 에러를 볼 수 있다^^..  부끄럼파티

 

+++ 실수한 생각들.... +++

과정 2에서 출력값을 보았으나,

key-value로 묶여있어 dict로 묶여나왔다는 착각을 했다. dict와 list의 혼종처럼 취급하는 실수를 했다..

그래서 과정 3에서 for문으로 내용을 검사해야한다고 생각하고, 또 이중 list-tuple의 함정에 빠졌다...ㅠㅠ

전체적으로 사용미숙이라고 봐야겠다..

 

 

 

그러니 다시 생각해보자.

sorted_list에서 v의 값은 무엇일까?

 

print(v) 는 list내의 각 튜플이다.  

(3,3)  (2,1)   (1,1)  (4,1)

 

sorted_list[0] = (3,3)

그래서 v를 for문으로 돌릴 것이아니라 내림차순으로 정리된 리스트에서 [0]을 뽑으면 튜플이 나온다는 것!

깨달음을 얻고 다시 코드를 작성하였다.

 

if sorted_list[0][1] > sorted_list[1][1]:
    answer = sorted_list[0][0]
    return print(answer)    # answer는 value값에 해당하는 key값

else:  #1, 2번째 value값을 비교해서 같으면 -1 출력
    sorted_list[0][1] = sorted_list[1][1]
    answer = -1
    return print(answer)

 

 

정상적 작동하는 것을 본 후,, if를 elif로 바꾸고

배열이 1개일 경우 key값을 출력해주는 코드를 더해주었다...

if len(sorted_list) == 1:  # key-value값이 하나만 존재하는 경우
    answer = sorted_list[0][1]
    return answer

 

이걸 맨위에 넣은 이유는

만약 배열이 1개면 아래 두 개는 시작부터 오류가 나기때문이다.

 

 

..끗..

 


느낀점: 

 

진짜....ㅠㅠ

답지 안보겠다고 오기부리다가 이 문제에 이틀치 알고리즘 시간을 부었따....

보람은 찬데 너무 힘들었다

 

dict, list, tuple활용을 많이 해보고, 그리고 중간중간 디버깅..꼭꼭...출력꼭꼭...

 

 

기억해 범위연산자 [0:1]

람다도 lambda 빨리 공부해서 넣어라