534. 打劫房屋 II

534. 打劫房屋 II

中文English

在上次打劫完一条街道之后,窃贼又发现了一个新的可以打劫的地方,但这次所有的房子围成了一个圈,这就意味着第一间房子和最后一间房子是挨着的。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警。

给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,在不触动报警装置的情况下, 你最多可以得到多少钱 。

样例

样例1

输入: nums = [3,6,4]
输出: 6

样例2

输入: nums = [2,3,2,3]
输出: 6

注意事项

这题是House Robber的扩展,只不过是由直线变成了圈

输入测试数据 (每行一个参数)如何理解测试数据?
class Solution:
    """
    @param nums: An array of non-negative integers.
    @return: The maximum amount of money you can rob tonight
    """
    '''
    大致思路:
    1.房子0和n - 1不能同时偷,要么不偷0 ,要么不偷n - 1
    大致解释:反正最终结果肯定是要么不偷0 ,要么不偷n - 1,所以只需要把这两种情况都考虑出来就可以了
    
    只需要[0 : n - 1] 和 [1 : n] 这两种情况的max(dp1[l - 2],dp2[l - 2])的最大值即可
    '''
    def houseRobber2(self, nums):
        if not nums or len(nums) == 0:return 0
        if len(nums) <= 2:return max(nums)

        #初始化
        l = len(nums)
        #只赋予l - 1的长度即可
        dp1 = [0 for _ in range(l - 1)] 
        dp2 = [0 for _ in range(l - 1)] 
        dp1[0],dp1[1] = nums[0],max(nums[:2])
        dp2[0],dp2[1] = nums[1],max(nums[1],nums[2])

        for i in range(l - 1):
            if i - 2 >= 0:
                dp1[i] = max(dp1[i - 2] + nums[i],dp1[i - 1])

        #此时dp2[0] 对应的是nums[1] 往后退了一个
        for j in range(1, l):
            if j - 2 >= 0 and j + 1 < l:
                dp2[j] = max(dp2[j - 2] + nums[j + 1],dp2[j - 1])
        
        return max(dp1[l - 2],dp2[l - 2])
原文地址:https://www.cnblogs.com/yunxintryyoubest/p/13061056.html