1. 程式人生 > >leetcode198. House Robber/213. House Robber II

leetcode198. House Robber/213. House Robber II

題目描述

計劃盜竊同一條街道上房子裡的錢。不能同時盜竊兩個相鄰的房間,否則會觸發警報。問在不觸動警報的情況下最多能拿到多少錢?

例子 Example 1:

Input: [1,2,3,1] Output: 4

Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3). Total amount you can rob = 1 + 3 = 4.

Example 2:

Input: [2,7,9,3,1] Output: 12

Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1). Total amount you can rob = 2 + 9 + 1 = 12.

思想 (DP) dp[i] 表示截止到第i家偷到的最多錢數。 兩種情況:偷了第i家nums[i] + dp[i-2];沒偷第i家dp[i-1] 狀態方程:dp[i] = max(dp[i-1], dp[i-2] + nums[i])

解法 複雜度:時間O(n),空間O(n)

class Solution(object):
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        dp = [0] *
(n+2) for i in range(2, n+2): dp[i] = max(dp[i-1], dp[i-2] + nums[i-2]) return dp[-1]

解法 - 空間優化 複雜度:時間O(n),空間O(1)

class Solution(object):
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        cur = pre = 0
        for num in
nums: pre, cur = cur, max(cur, pre + num) return cur

題目描述

計劃盜竊同一條環形街道上房子裡的錢。不能同時盜竊兩個相鄰的房間,否則會觸發警報。問在不觸動警報的情況下最多能拿到多少錢?

例子 Example 1:

Input: [2,3,2] Output: 3

Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2), because they are adjacent houses.

Example 2:

Input: [1,2,3,1] Output: 4

Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3). Total amount you can rob = 1 + 3 = 4.

思想 由於是環形街道,所以除了考慮相鄰兩家不能同時偷外,首尾兩家也不能同時偷。 (DP - 法1 - 偷不偷第一家?) 兩種情況:不偷第一家(不能偷第2家) + 偷第一家(不能偷最後一家),然後類似198. House Robber。 (DP - 法2) 拆分成兩種情況:不考慮第一家 + 不考慮最後一家,然後類似198. House Robber。 邊界:考慮只有一家的情況

解法1 複雜度:時間O(n),空間O(1)

class Solution(object):
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        return max(nums[0] + self.helper(nums[2:-1]), self.helper(nums[1:]))
    
    def helper(self, nums):
        cur = pre = 0
        for num in nums:
            pre, cur = cur, max(cur, pre + num)
        return cur

解法2 複雜度:時間O(n),空間O(1)

class Solution(object):
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 1:
            return nums[0]
        return max(self.helper(nums[1:]), self.helper(nums[:-1]))
    
    def helper(self, nums):
        cur = pre = 0
        for num in nums:
            pre, cur = cur, max(cur, pre + num)
        return cur