1. House Robber II
題目整理
給一排房子的金額 nums,小偷不能偷相鄰房子;但這次房子排成一圈,所以第一間與最後一間也相鄰。請回傳在不觸發警報下可偷到的最大金額。
- 若只有一間房子,答案就是該房子的金額。
- 因為第一間與最後一間不能同時偷,所以問題可拆成兩個線性版本:
nums[0:n-1]與nums[1:n]。
解法說明
線性 House Robber 的狀態是:走到目前房子時,最佳答案只和「上一間以前的最佳」與「上上間以前的最佳」有關。環狀限制只需要避免首尾同時被選,因此分別計算「排除最後一間」與「排除第一間」,取最大值。
from typing import List
class Solution:
def rob(self, nums: List[int]) -> int:
if not nums:
return 0
if len(nums) == 1:
return nums[0]
def rob_line(values: List[int]) -> int:
two_back = 0
one_back = 0
for money in values:
two_back, one_back = one_back, max(one_back, two_back + money)
return one_back
return max(rob_line(nums[:-1]), rob_line(nums[1:]))
Interview Explanation Flow
Step 1: Point out the circular constraint
"This is similar to the regular House Robber problem, but the first and last houses are adjacent, so they cannot both be robbed."
Step 2: Split into two linear cases
"To remove the circular dependency, I split the problem into two normal linear robber problems: rob houses from index 0 to n - 2, or rob houses from index 1 to n - 1."
case 1: exclude the last house -> nums[0:n-1]
case 2: exclude the first house -> nums[1:n]
Example:
nums = [2, 3, 2]
exclude last -> [2, 3] -> 3
exclude first -> [3, 2] -> 3
answer = max(3, 3) = 3
Step 3: Reuse the linear DP helper
"For each linear case, I use the standard recurrence: at each house, either skip it and keep the previous best, or rob it and add its value to the best from two houses ago."
new_best = max(previous_best, two_back + current_money)
Step 4: Discuss edge cases
"If there is only one house, I return its value directly because the split would otherwise create an empty case."
Step 5: Complexity
"Time complexity is O(n) because we run two linear scans. Space complexity is O(1) if we avoid counting slicing and only keep two DP variables."
Possible follow-ups
- Why two cases? "Every valid answer must exclude either the first house or the last house, so these two cases cover all possibilities."
- Why not use a full DP array? "The recurrence only depends on the previous two states, so two variables are enough."
中文:面試時先說清楚環狀限制,再拆成兩個線性 House Robber 問題。