[PGS] 귤고르기 딕셔너리 최적화, Counter #99클럽9일차 #TIL

2024. 4. 8. 00:47_Study/Baekjoon

728x90


#99클럽 #99일지 #코딩테스트 #개발자스터디 #항해 #TIL #프로그래머스
 

✅ 귤고르기 설명

✅ 해결 방법

✅ 발생한 문제와 방안

✅ 최종적인 해결 방법

✅ 최적화 방안

 
 

그래서 오늘의 TIL(Today I Learned) 학습 키워드 
 

✨ 그리디

✨ 딕셔너리 Counter


 

 귤고르기 설명

 

99클럽 미들러 난이도 귤 고르기로 그리디, 딕셔너리 Counter 하는 방법을 알아보겠습니다.
 
코딩테스트 연습 - 귤 고르기 | 프로그래머스 스쿨 (programmers.co.kr)

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


 
 

✅ 문제설명

 

경화는 과수원에서 귤을 수확했습니다. 경화는 수확한 귤 중 'k'개를 골라 상자 하나에 담아 판매하려고 합니다. 그런데 수확한 귤의 크기가 일정하지 않아 보기에 좋지 않다고 생각한 경화는 귤을 크기별로 분류했을 때 서로 다른 종류의 수를 최소화하고 싶습니다.

예를 들어, 경화가 수확한 귤 8개의 크기가 [1, 3, 2, 5, 4, 5, 2, 3] 이라고 합시다. 경화가 귤 6개를 판매하고 싶다면, 크기가 1, 4인 귤을 제외한 여섯 개의 귤을 상자에 담으면, 귤의 크기의 종류가 2, 3, 5로 총 3가지가 되며 이때가 서로 다른 종류가 최소일 때입니다.

경화가 한 상자에 담으려는 귤의 개수 k와 귤의 크기를 담은 배열 tangerine이 매개변수로 주어집니다. 경화가 귤 k개를 고를 때 크기가 서로 다른 종류의 수의 최솟값을 return 하도록 solution 함수를 작성해주세요.

제한사항
1 ≤ k ≤ tangerine의 길이 ≤ 100,000
1 ≤ tangerine의 원소 ≤ 10,000,000

 

 


 

✅ 해결 방법

 

일단 크기별로 몇 개가 있는 지 개수를 정리합니다. 그리고 판매개수가 될때 까지 가장 많은 개수의 종류 부터 담으면 해결가능할거 같습니다. 일단 크기별로 담기 위해서는, 배열의 요소 순으로 정리해야합니다. 배열을 한 번 다 돌아야할 거 같은데 N의 시간복잡도보다 뛰어난 방법이 있을까요?

 

배열의 index를 상자인 셈 치고 하나씩 넣으려고 했는데, 생각해보니 어떻게 정렬을 할까요? 딕셔너리로 만들어야할까요? 귤의 크기 종류도 10,000,000이라서 더 좋은 방법이 있을거 같습니다. 배열 하나를 통으로 썼다간 중간에 메모리 비는게 너무 많을거 같네요.


✅ 발생한 문제와 방안

def solution(k, tangerine):
    answer = 0
    my_dict = dict()
    for item in tangerine:
        my_dict[item] += 1
    print(my_dict)
    
    return answer

 

keyError: 1이 발생했습니다. for 문 맨처음 item에서 딕셔너리에 해당하는 키 값이 없기 때문에 발생합니다.

 

def solution(k, tangerine):
    answer = 0
    my_dict = dict()
    for item in tangerine:
        if item in my_dict:
            my_dict[item] += 1
        else:
            my_dict[item] = 1
    print(my_dict)
    
    return answer

 

이제 크기별로 개수는 모두 세었으니 딕셔너리를 내림차순 정렬하고 K만큼 채워야합니다.

 

 


✅ 최종적인 해결 방법

 

def solution(k, tangerine):
    answer = 0
    count = 0
    my_dict = dict()
    for item in tangerine:
        if item in my_dict:
            my_dict[item] += 1
        else:
            my_dict[item] = 1
    sorted_dict = sorted(my_dict.items(), key=lambda x: x[1], reverse=True)
    for item in sorted_dict:
        if count < k:
            answer += 1
            count += item[1]
        else: break
    return answer

 


 

✅ 최적화 방안

 

counter이라는 라이브러리를 사용하면 요소의 개수를 빠르고 편리하게 확인할 수 있습니다. 특히 문자열 같이 알파벳의 개수를 세는 문제는 counter이 편리할 수 있습니다. most_common() 메소드를 사용하면 (요소, 빈도수)로 정리되기 때문에 요소의 개수를 이용하는 문제에서 사용가능합니다.

 

# 문자열에서 각 문자의 개수를 세기
my_string = "hello"
counter = Counter(my_string)
print(counter)  # 출력: Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})

 

from collections import Counter

def solution(k, tangerine):
    my_counter = Counter(tangerine)
    answer = 0
    count = 0

    for _, count_per_tangerine in my_counter.most_common():
        if count < k:
            answer += 1
            count += count_per_tangerine
        else:
            break

    return answer

 

좌 : 최적화전 / 우 : 최적화 후

 

참고자료


https://korbillgates.tistory.com/95