티스토리 뷰

728x90
반응형

문제

당신은 전문털이범이다. 어느 집에서든 돈을 훔쳐올 수 있지만 경보 시스템 때문에 바로 옆집은 훔칠 수 없고 한 칸 이상 떨어진 집만 가능하다. 각 집에는 훔칠 수 있는 돈의 액수가 입력 값으로 표기되어 있다. 훔칠 수 있는 가장 큰 금액을 출력하라.

입력 : [1, 2, 3, 1]
출력: 4
설명
첫 번째 집에서 1, 세번째 집에서 3, 따라서 1 + 3 = 4

입력 : [2, 7, 9, 3, 1]
출력 : 12
설명
첫 번째 집에서 2, 세 번째 집에서 9, 다섯 번째 집에서 1, 따라서 2 + 9 + 1 = 12이다.

코드

"""
fixme. https://leetcode.com/problems/house-robber/
fixme. Q88. 집도둑
fixme. 당신은 전문털이범이다. 어느 집에서든 돈을 훔쳐올 수 있지만 경보 시스템 때문에
fixme. 바로 옆집은 훔칠 수 없고 한 칸 이상 떨어진 집만 가능하다.
fixme. 각 집에는 훔칠 수 있는 돈의 액수가 입력 값으로 표기되어 있다. 훔칠 수 있는 가장 큰 금액을 출력하라.
fixme. 입력 : [1, 2, 3, 1]
fixme. 출력 : 4
fixme. 설명
fixme. 첫 번째 집에서 1, 세번째 집에서 3, 따라서 1 + 3 = 4
fixme. 입력 : [2, 7, 9, 3, 1]
fixme. 출력 : 12
fixme. 설명
fixme. 첫 번째 집에서 2, 세 번째 집에서 9, 다섯 번째 집에서 1, 따라서 2 + 9 + 1 = 12이다.
"""

from typing import List
import collections

class Solution:
    def rob(self, nums: List[int]) -> int:
        def _rob(i: int) -> int:
            if i < 0:
                return 0
            return max(_rob(i - 1), _rob(i - 2) + nums[i])

        return _rob(len(nums) - 1)
    def robDP(self, nums: List[int]) -> int:
        if not nums:
            return 0
        if len(nums) <= 2:
            return max(nums)

        dp = collections.OrderedDict()
        dp[0], dp[1] = nums[0], max(nums[0], nums[1])

        for i in range(2, len(nums)):
            dp[i] = max(dp[i-1], dp[i-2] + nums[i])
        print(dp)
        return dp.popitem()[1]

풀이

재귀 구조 브루트 포스

바로 옆집은 훔칠 수 없으니 현재 집과 옆집 숫자 중의 최댓값을 구하고, 한 집 건넛집과 현재 집의 합과 비교해서 더 큰 값을 구해나가는 식으로 풀어나간다. 이렇게 하면 피보나치 수열과 거의 유사하여 재귀로 풀 수 있다.

아래는 nums = [9,3,9,8], i = 3인 경우에 변수의 흐름이다.

이 풀이는 시간 제한으로 풀리지 않는다.

타뷸레이션

알고리즘은 동일하고, 이미 계산한 값을 dp에 저장한다.

원래 딕셔너리는 입력 순서가 유지되지 않았으나 파이썬 3.7+부터는 유지된다. 하지만 파이썬의 낮은 버전에서도 순서가 유지될 수 있도록 명시적으로 collections.OrderedDict()로 선언했다.

가장 마지막 값의 추출은 popitem()을 사용한다. 리스트의 pop()과 동일한 역할을 하는데, 딕셔너리에도 pop()이 있지만 반드시 키를 지정해야 하고 해당 키의 아이템을 추출하는 역할을 한다. 딕셔너리에서 가장 마지막 아이템을 추출하기 위해서는 popitem()을 사용해야 한다.



출처
파이썬 알고리즘 인터뷰 (글 : 박상길 그림 : 정진호) [책만]

728x90
반응형
댓글
반응형
250x250
글 보관함
최근에 달린 댓글
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Total
Today
Yesterday
링크