Python version-LeetCode learning: house robbery (, II, III)

198. House Robbery

You are a professional thief, planning to steal houses along the street. There is a certain amount of cash hidden in each room. The only constraint that affects your theft is that the adjacent houses are equipped with interconnected anti-theft systems. If two adjacent houses are broken into by a thief at the same night, the system will automatically alarm . Given an array of non-negative integers representing the amount of money stored in each house, calculate the maximum amount that can be stolen overnight without touching the alarm device.

Example 1: Input: [1,2,3,1] Output: 4
Explanation: Steal house 1 (amount = 1), then steal house 3 (amount = 3).
           The highest amount stolen = 1 + 3 = 4.

Source: LeetCode
Link: https://leetcode-cn.com/problems/house-robber

Method 1: Dynamic programming

class Solution:
    def rob(self, nums: List[int]) -> int:
        n=len(nums)
        dp=[0 for i in range(n+2)]
        # n-1 是为了让i和nums对其
        for i in range(n-1,-1,-1):
            # 两种状态比对,不抢:当前所获等于上一次的获得;抢:当前所获等于当前房屋(nums[i])加上上次所获
            dp[i]=max(dp[i+1],nums[i]+dp[i+2])
        
        return dp[0]

Method 2: Recursion

class Solution:
    def rob(self, nums: List[int]) -> int:
        global memo
        memo=[-1 for i in range(len(nums))]
        # 自顶向上
        return self.dp(nums,0)
    
    def dp(self,nums: List[int],start: int)-> int:
        if start>=len(nums):
            return 0
        if memo[start]!=-1: return memo[start]
        rst =max(
            # 不抢,去下家
            self.dp(nums,start+1),
            # 抢,让后去下下家
            nums[start]+ self.dp(nums,start+2)
            )
        memo[start]=rst

        return rst

 

 213. House Robbery II

You are a professional thief. You plan to steal houses along the street. There is a certain amount of cash hidden in each house. All houses in this place are in a circle, which means that the first house and the last house are next to each other. At the same time, adjacent houses are equipped with interconnected anti-theft systems. If two adjacent houses are broken into by a thief at the same night, the system will automatically alarm. Given an array of non-negative integers representing the amount of storage in each house, calculate the highest amount you can steal without triggering the alarm device.

Example 1: Input: [2,3,2] Output: 3
Explanation: You cannot steal house 1 (amount = 2) first, and then steal house 3 (amount = 2) because they are adjacent.

Source: LeetCode
Link: https://leetcode-cn.com/problems/house-robber-ii

Method 1: Dynamic programming

class Solution:
    def rob(self, nums: List[int]) -> int:
        n=len(nums)
        if n==0 : return 0
        if n==1: return nums[0]

        return max(self.robPlan(nums,0,n-2),self.robPlan(nums,1,n-1))
    
    def robPlan(self,nums:List[int],start:int,end:int)-> int:
        # 初始化
        state_0,state_1=0,0
        rst=0
        for i in range(end,start-1,-1):
            # 不抢or抢,state_0:上次没抢后的金额,state_1:上次抢过后的金额
            # rst:这次抢与不抢的比较的结果
            rst=max(state_0,state_1+nums[i])
            # 这次不抢,就作为下次抢的获利基数
            state_1=state_0
            # 这次抢的结果,就作为下次不抢的获利数
            state_0=rst

        return rst

Reference: https://leetcode-cn.com/problems/house-robber-ii/solution/213-da-jia-jie-she-iidong-tai-gui-hua-jie-gou-hua-/

337. House Robbery III

 After robbing a street and a circle of houses last time, the thief discovered a new area where theft could be done. There is only one entrance to this area, which we call the "root". In addition to the "root", every house has one and only one "parent" house connected to it. After some reconnaissance, the clever thief realized that "all the houses in this place are arranged like a binary tree." If two directly connected houses are robbed on the same night, the house will automatically call the police. Calculate the maximum amount a thief can steal overnight without triggering the alarm.

Example 1: Input: [3,2,3,null,3,null,1]

     3
    / \
   2   3
    \   \ 
     3   1

Output: 7 
Explanation: The maximum amount a thief can steal in one night = 3 + 3 + 1 = 7.

Source: LeetCode
Link: https://leetcode-cn.com/problems/house-robber-iii
Method 1:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def __init__(self):
        self.memo=collections.defaultdict(int)

    def rob(self, root: TreeNode) -> int:
        if root == None: return 0

        if root in self.memo:
            return self.memo[root]
        # 抢,就查找当前值以及下下家(孙节点)的值,并求和
        do_it=root.val \
        +(0 if root.left==None else self.rob(root.left.left)+self.rob(root.left.right))\
        +(0 if root.right==None else self.rob(root.right.left)+self.rob(root.right.right))
        # 不抢,不抢当前值就抢下家(儿子节点)的值,并求和
        not_do=self.rob(root.left)+self.rob(root.right)
        # 取最大值
        rst=max(do_it,not_do)

        self.memo[root]=rst
        return rst

 

Guess you like

Origin blog.csdn.net/guyu1003/article/details/107484794