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