From 50579e53ce2a27fac07b071b1e594bb0255ee86a Mon Sep 17 00:00:00 2001 From: Hiro Funatsuka Date: Thu, 7 May 2026 22:21:11 +0900 Subject: [PATCH] Solve house robber ii --- 213_house_robber_ii/problem.md | 1 + 213_house_robber_ii/step1.md | 29 +++++++++++++++++++++++++++++ 213_house_robber_ii/step2.md | 26 ++++++++++++++++++++++++++ 213_house_robber_ii/step3.md | 28 ++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 213_house_robber_ii/problem.md create mode 100644 213_house_robber_ii/step1.md create mode 100644 213_house_robber_ii/step2.md create mode 100644 213_house_robber_ii/step3.md diff --git a/213_house_robber_ii/problem.md b/213_house_robber_ii/problem.md new file mode 100644 index 0000000..babd4b9 --- /dev/null +++ b/213_house_robber_ii/problem.md @@ -0,0 +1 @@ +## 問題: [213 House Robber II](https://leetcode.com/problems/house-robber-ii/description/) diff --git a/213_house_robber_ii/step1.md b/213_house_robber_ii/step1.md new file mode 100644 index 0000000..0c87640 --- /dev/null +++ b/213_house_robber_ii/step1.md @@ -0,0 +1,29 @@ +# Step 1 + +- $i$番目まで訪れた時の最大利益$maxAmount[i]$は$max(maxAmount[i - 1], maxAmount[i - 2] + nums[i])$ +- 円形のため、$0\le i \le nums.size -2$の範囲の最大利益と$1\le i \le nums.size -1$の範囲の最大利益のうち大きい方を返す + +```python +class Solution: + def rob(self, nums: List[int]) -> int: + if len(nums) <= 2: + return max(nums) + first_max_amount_prev_2 = nums[0] + first_max_amount_prev_1 = max(nums[0], nums[1]) + for i in range(2, len(nums) - 1): + current_max_amount = max(first_max_amount_prev_1, first_max_amount_prev_2 + nums[i]) + first_max_amount_prev_2 = first_max_amount_prev_1 + first_max_amount_prev_1 = current_max_amount + + second_max_amount_prev_2 = nums[1] + second_max_amount_prev_1 = max(nums[1], nums[2]) + for i in range(3, len(nums)): + current_max_amount = max(second_max_amount_prev_1, second_max_amount_prev_2 + nums[i]) + second_max_amount_prev_2 = second_max_amount_prev_1 + second_max_amount_prev_1 = current_max_amount + return max(first_max_amount_prev_1, second_max_amount_prev_1) +``` + +時間計算量: $O(n)$ + +空間計算量: $O(1)$ diff --git a/213_house_robber_ii/step2.md b/213_house_robber_ii/step2.md new file mode 100644 index 0000000..8ac66a7 --- /dev/null +++ b/213_house_robber_ii/step2.md @@ -0,0 +1,26 @@ +# Step 2 + +```python +class Solution: + def rob(self, nums: List[int]) -> int: + if len(nums) <= 2: + return max(nums) + + def rob_linear(start, end): + profit_two_back = nums[start] + profit_one_back = max(nums[start], nums[start + 1]) + + for i in range(start + 2, end): + current_profit = max(profit_one_back, profit_two_back + nums[i]) + profit_two_back = profit_one_back + profit_one_back = current_profit + + return profit_one_back + + return max(rob_linear(0, len(nums) - 1), rob_linear(1, len(nums))) + +``` + +時間計算量: $O(n)$ + +空間計算量: $O(1)$ diff --git a/213_house_robber_ii/step3.md b/213_house_robber_ii/step3.md new file mode 100644 index 0000000..5ff7786 --- /dev/null +++ b/213_house_robber_ii/step3.md @@ -0,0 +1,28 @@ +# Step 3 + +```python +class Solution: + def rob(self, nums: List[int]) -> int: + if len(nums) <= 2: + return max(nums) + + def rob_linear(start, end): + profit_two_back = nums[start] + profit_one_back = max(nums[start], nums[start + 1]) + + for i in range(start + 2, end): + current_profit = max(profit_one_back, profit_two_back + nums[i]) + profit_two_back = profit_one_back + profit_one_back = current_profit + + return profit_one_back + + return max(rob_linear(0, len(nums) - 1), rob_linear(1, len(nums))) + +``` + +1回目: 2分 57秒 + +2回目: 2分 18秒 + +3回目: 2分 14秒