본문 바로가기
코딩테스트

더 맵게

by 느림보어른 2021. 5. 24.

문제풀이

효율성 실패

이번 코딩 문제는 힙을 이용해야 하는 문제인데 내가 처음 문제를 풀었던 코드는 한 번 과정을 거칠 때마다 sort()를 이용해 정렬을 하였다. 결국 이것이  비효율적인 시간을 지출해 문제를 통과하지 못했다.

효율성 해결

import heapq

def solution(scoville, K):
    answer = 0
    
    scoville.sort()
    if scoville[0] == 0 and scoville[1] == 0:
        return -1
        
    heapq.heapify(scoville) 
    
    while(scoville[0] < K and len(scoville) > 1):
        x = heapq.heappop(scoville)
        y = heapq.heappop(scoville)
        new_scoville = min(x, y) + max(x, y) * 2
        
        heapq.heappush(scoville, new_scoville)
        
        answer += 1
    
    if scoville[0] < K:
        answer = -1
    
    return answer

heapq를 import 하여 따로 heap을 생성하는 함수를 만들지는 않았다. heap에 관한 자세한 내용은 아래에 첨부한다.

알고리즘

Heap

부모의 값이 자식의 값보다 항상 크다(자식의 값 <= 부모의 값)라는 조건을 만족하는 완전 이진트리이다. (반대의 경우도 힙이라고 한다.)

또 형제의 대소 관계가 정해져 있지 않으므로 부분 순서 트리(partial ordered tree)라고도 한다.

 

힙을 배열에 저장하면 부모 인덱스, 왼쪽 자식, 오른쪽 자식은 다음과 같은 관계가 성립한다.

원소 a[i]에서

  • 부모: a[(i-1) // 2]
  • 왼쪽 자식: a[i * 2 +1]
  • 오른쪽 자식: a[i * 2 + 2]

힙은 일반적으로, 리스트에서 가장 작은(또는 가장 큰) 요소에 반복적으로 접근하는 프로그램에 유용하다.

힙을 사용하면 가장 작은(또는 가장 큰) 요소를 처리하는 시간 복잡도는 O(n)이고, 그 외의 조회, 추가, 수정을 처리하는 시간 복잡도는 O(log n)이다.                               

Heap 정렬의 특징

힙에서 최댓값은 루트에 위치한다는 특징을 이용한다. 구체적으로 다음의 과정을 반복한다.

  1. 힙의 최댓값인 루트를 꺼낸다.
  2. 마지막 원소(가장 하단의 오른쪽에 위치한 원소)를 루트로 이동한다.
  3. 루트에서 시작하여 자신보다 값이 큰 자식과 자릴 바꾸고 아래쪽으로 내려가는 작업을 반복한다. 자식의 값이 작거나 리프의 위치에 도달하면 종료한다.

출처

문제: 프로그래머스 코딩 테스트 연습, https://programmers.co.kr/learn/challenges

 

코딩테스트 연습

기초부터 차근차근, 직접 코드를 작성해 보세요.

programmers.co.kr

파이썬 자료구조와 알고리즘 - 미아 스타인 저/최길우 

Do it! 자료구조와 함께 배우는 알고리즘 입문 : 파이썬 편 - 시바타 보요 저/강민 역

'코딩테스트' 카테고리의 다른 글

삼각 달팽이  (0) 2021.05.26
문자열 압축  (0) 2021.05.26
짝지어 제거하기  (0) 2021.05.25
내적  (0) 2021.05.25
가장 먼 노드  (0) 2021.05.23