새소식

⌨️ Algorithms/프로그래머스

[Python] 프로그래머스 Lv2_더 맵게

2023. 1. 2. 23:42

  • -

https://school.programmers.co.kr/learn/courses/30/lessons/42626

 

프로그래머스

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

programmers.co.kr

 

  • 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해
  • 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같이 특별한 방법으로 섞어 새로운 음식을 만듦
    • 섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2)
  • 모든 음식의 스코빌 지수가 K 이상이 될 때까지 반복해서 섞음
  • scoville: Leo가 가진 음식의 스코빌 지수를 담은 배열
  • K: 원하는 스코빌 지수
  • 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 섞어야 하는 최소 횟수를 return

제한 사항

  • scoville의 길이는 2 이상 1,000,000 이하
  • K는 0 이상 1,000,000,000 이하
  • scoville의 원소는 각각 0 이상 1,000,000 이하
  • 모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우에는 -1을 return

 

"""
입출력 예시)

scoville = [1, 2, 3, 9, 10, 12], K = 7 -> 2
"""

 

# scoville = [1, 2, 3, 9, 10, 12], K = 7 -> 2

# 스코빌 지수가 1인 음식과 2인 음식을 섞었을 때  되는 음식의 스코빌 지수
#   -> 새로운 음식의 스코빌 지수 = 1 + (2 * 2) = 5
#   -> 가진 음식의 스코빌 지수 = [5, 3, 9, 10, 12]

# 스코빌 지수가 3인 음식과 5인 음식을 섞었을 때  되는 음식의 스코빌 지수
#   -> 새로운 음식의 스코빌 지수 = 3 + (5 * 2) = 13
#   -> 가진 음식의 스코빌 지수 = [13, 9, 10, 12]

# -> 모든 음식의 스코빌 지수가 7 이상으로 됨
# => 섞은 횟수: 2회

 

 

## 의사코드 ##

# import heapq
# -> 주어진 scoville을 최소 힙 형태로 정렬한 다음 사용

# 가장 맵지 않은 음식의 스코빌 지수 = heapq.heappop(scoville) 
#   -> scoville의 최솟값인 scoville[0]을 반환해서 first에 저장하고, scoville에서 삭제 후 다시 scoville[0]에 scoville의 최솟값을 정렬

# 두 번째로 맵지 않은 음식의 스코빌 지수 = heapq.heappop(scoville) 
#   -> scoville의 최솟값인 scoville[0]을 반환해서 second에 저장하고, scoville에서 삭제 후 다시 scoville[0]에 scoville의 최솟값을 정렬

# 섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2)
# heapq.heappush(scoville, new)
#   -> scoville에 섞은 음식의 스코빌 지수를 추가하고, 다시 scoville[0]에 scoville의 최솟값을 정렬

# 섞은 횟수 -> 반복문 돌리면서 cnt += 1

# 모든 음식의 스코빌 지수가 K 이상이면 break -> 스코빌 지수가 K보다 작은 경우 반복문 실행


# + 
# 새로운 스코빌 지수가 추가된 후의 가진 음식의 스코빌 지수 배열이 입출력 예시 설명에 나온 순서 그대로 진행되어야 될 필요 없음
# -> heapq는 최소 힙 형태로 정렬하는 거라서 index:0인 값에 최솟값을 정렬해 주고 그 뒤에 나오는 값들은 정렬 x
# (최소 힙은 최솟값을 빠르게 찾기 위한 알고리즘이지, 작은 순서대로 정렬하는 알고리즘 X!)
# 어차피 우리는 스코빌 지수 배열에서 최솟값만 계속 꺼내면 됨

 

  • heapify()
    • 리스트를 최소 힙으로 변환
      • (heapq는 최소 힙 형태로 정렬)
    • sort()처럼 원본 리스트 자체를 정렬하는 거라 반환 값이 None
      • 정렬된 힙을 출력할 때는 원본 리스트 변수를 출력하면 됨

 

import heapq
scoville = [1, 2, 3, 9, 10, 12]
heap = heapq.heapify(scoville)
print(heap)

"""
None
"""

# -> heapify는 sort()처럼 원본 리스트 자체를 정렬하는 거라 반환 값이 None
ex = [13, 2, 1, 5, 10]
print('원본:', ex)

import heapq
heapq.heapify(ex)
print('heapify:', ex)

"""
원본: [13, 2, 1, 5, 10]
heapify: [1, 2, 13, 5, 10]
"""

# -> 따로 변수로 선언하지 않고 heapq.heapify()한 다음 원본 리스트를 출력하면 정렬된 리스트 반환

 

 

 

첫 번째 시도

 

import heapq

def solution(scoville, K):
    answer = 0
    heapq.heapify(scoville) # scoville을 최소 힙 형태로 정렬

    for s in scoville:
        # 스코빌 지수가 K보다 작은 경우
        if s < K:
            first = heapq.heappop(scoville) # 가장 맵지 않은 음식의 스코빌 지수
            second = heapq.heappop(scoville) # 두 번째로 맵지 않은 음식의 스코빌 지수
            new = first + (second * 2) # 섞어 만든 새로운 음식의 스코빌 지수
            heapq.heappush(scoville, new) # 새로운 스코빌 지수를 scoville에 삽입
            answer += 1 # 섞은 횟수 + 1
    
    return answer

-> 추가 테스트 케이스 & 효율성 테스트 실패

'모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우에는 -1을 return' 부분을 까먹음...

 

 

통과한 코드

 

import heapq

def solution(scoville, K):
    answer = 0
    heapq.heapify(scoville) # scoville을 최소 힙 형태로 정렬

    # 스코빌 지수가 K보다 작은 경우
    while scoville[0] < K:
        first = heapq.heappop(scoville) # 가장 맵지 않은 음식의 스코빌 지수
        second = heapq.heappop(scoville) # 두 번째로 맵지 않은 음식의 스코빌 지수
        new = first + (second * 2) # 섞어 만든 새로운 음식의 스코빌 지수
        heapq.heappush(scoville, new) # 새로운 스코빌 지수를 scoville에 삽입
        answer += 1 # 섞은 횟수 + 1

        # 모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우
        if len(scoville) == 1 and scoville[0] < K:
            return -1 # -1을 return 
    
    return answer

-> '모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우에는 -1을 return' 추가

'모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우' => scoville에 하나의 원소만 있고, scoville[0]이 K보다 작은 경우

 

 

 

  • 과정 확인
# scoville = [1, 2, 3, 9, 10, 12, K = 7 

"""
정렬된 scoville: [1, 2, 3, 9, 10, 12]
__________________________________________________ 

first: 1
second: 2
남은 scoville: [3, 9, 10, 12] 

새로운 스코빌: 5
추가된 scoville: [3, 5, 10, 12, 9]
__________________________________________________ 

first: 3
second: 5
남은 scoville: [9, 12, 10] 

새로운 스코빌: 13
추가된 scoville: [9, 12, 10, 13]
__________________________________________________ 
"""

 

 

 

참고) 

 

https://velog.io/@gnwjd309/python-heap

 

[Python] 파이썬 힙(Heap) 사용하기

Heap은 어떻게 구현하나요!

velog.io

 

https://yunaaaas.tistory.com/36

 

[Python 자료구조] Heap (힙)

파이썬에서의 Heap ?! Python에서의 Heap은 heapq 모듈과 Queue 모듈의 PriorityQueue 클래스를 통해 heapq를 제공합니다. 단, MinHeap으로 구현되어있어 가장 앞에 있는 원소가 가장 작은 원소가 됩니다. heapq 와

yunaaaas.tistory.com

 

https://velog.io/@limeorange/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Python-%EB%8D%94-%EB%A7%B5%EA%B2%8C

 

[프로그래머스 / Python] 더 맵게

유형 힙(Heap)문제 설명 매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두

velog.io

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다!