From 6f436175c0a315ba4780ebd764bcab815f15dd83 Mon Sep 17 00:00:00 2001 From: seal_azarashi Date: Sun, 6 Oct 2024 22:39:14 +0900 Subject: [PATCH 1/4] =?UTF-8?q?step=201=20=E9=80=94=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arai60/Dynamic_Programming/house-robber-ii.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 arai60/Dynamic_Programming/house-robber-ii.md diff --git a/arai60/Dynamic_Programming/house-robber-ii.md b/arai60/Dynamic_Programming/house-robber-ii.md new file mode 100644 index 0000000..a76ae36 --- /dev/null +++ b/arai60/Dynamic_Programming/house-robber-ii.md @@ -0,0 +1,43 @@ +# 213. House Robber II + +LeetCode URL: https://leetcode.com/problems/house-robber-ii/description/ + +この問題は Java で解いています。 +各解法において、メソッドが属するクラスとして `Solution` を定義していますが、これは Java の言語仕様に従い、コードを実行可能にするために必要なものです。このクラス自体には特定の意味はなく、単にメソッドを組織化し、実行可能にするためのものです。 + +## Step 1 + +```java +/** + * 時間計算量: O(n): + * - O(n): 配列の先頭から末尾の要素を除いた全ての要素を対象に robHelper() を実行 + * - O(n): 配列2つ目の要素から末尾まで全ての要素を対象に robHelper() を実行 + * 空間計算量: O(1): 各走査で必要な変数等定数量の追加空間 + */ +class Solution { + public int rob(int[] nums) { + if (nums == null || nums.length == 0) { + return 0; + } + if (nums.length == 1) { + return nums[0]; + } + + return Math.max( + robHelper(0, nums.length - 1, nums), + robHelper(1, nums.length, nums) + ); + } + + private int robHelper(int start, int end, int[] nums) { + int twoBackMaxCount = 0, oneBackMaxCount = 0; + for (int i = start; i < end; i++) { + int maxCount = Math.max(twoBackMaxCount + nums[i], oneBackMaxCount); + + twoBackMaxCount = oneBackMaxCount; + oneBackMaxCount = maxCount; + } + return oneBackMaxCount; + } +} +``` From c27eff69c557827b82bfd0eef31b4a712fa13d26 Mon Sep 17 00:00:00 2001 From: seal_azarashi Date: Mon, 7 Oct 2024 06:56:23 +0900 Subject: [PATCH 2/4] step 1 & 2 --- arai60/Dynamic_Programming/house-robber-ii.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arai60/Dynamic_Programming/house-robber-ii.md b/arai60/Dynamic_Programming/house-robber-ii.md index a76ae36..5f3038f 100644 --- a/arai60/Dynamic_Programming/house-robber-ii.md +++ b/arai60/Dynamic_Programming/house-robber-ii.md @@ -7,6 +7,10 @@ LeetCode URL: https://leetcode.com/problems/house-robber-ii/description/ ## Step 1 +House Robber の拡張版のような問題。今回は家が円状に並んでおり、最初と最後の家が隣接する。 +隣接する最初と最後の家は同時に盗みに入れないため、配列から最初 or 最後の家を除いた計2つの配列を作り、それぞれで盗めるお金の最大値から、より大きいものが答えになる。 +(💭 ヘルパーメソッドの中身をどうするかについては [House Robber のプルリクエスト](https://github.com/seal-azarashi/leetcode/pull/33)で議論がされていますので、そちらも合わせてご覧いただけますと嬉しいです) + ```java /** * 時間計算量: O(n): @@ -41,3 +45,7 @@ class Solution { } } ``` + +## Step 2 + +他の方のプルリクエストに目を通したが、注目すべき事項はほぼ [House Robber の方](https://github.com/seal-azarashi/leetcode/pull/33)を解く際に把握出来ていたようなので、今回は割愛。 From 05c7a9d480e29878dee1feafb4f7f46be5685eb9 Mon Sep 17 00:00:00 2001 From: seal_azarashi Date: Mon, 7 Oct 2024 07:11:48 +0900 Subject: [PATCH 3/4] step 3 --- arai60/Dynamic_Programming/house-robber-ii.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/arai60/Dynamic_Programming/house-robber-ii.md b/arai60/Dynamic_Programming/house-robber-ii.md index 5f3038f..7ac64cc 100644 --- a/arai60/Dynamic_Programming/house-robber-ii.md +++ b/arai60/Dynamic_Programming/house-robber-ii.md @@ -49,3 +49,41 @@ class Solution { ## Step 2 他の方のプルリクエストに目を通したが、注目すべき事項はほぼ [House Robber の方](https://github.com/seal-azarashi/leetcode/pull/33)を解く際に把握出来ていたようなので、今回は割愛。 + +## Step 3 + +```java +/** + * 解いた時間: 約4分 + * 時間計算量: O(n): + * - O(n): 配列の先頭から末尾の要素を除いた全ての要素を対象に robHelper() を実行 + * - O(n): 配列2つ目の要素から末尾まで全ての要素を対象に robHelper() を実行 + * 空間計算量: O(1): 各走査で必要な変数等定数量の追加空間 + */ +class Solution { + public int rob(int[] nums) { + if (nums == null || nums.length == 0) { + return 0; + } + if (nums.length == 1) { + return nums[0]; + } + + return Math.max( + robHelper(0, nums.length - 1, nums), + robHelper(1, nums.length, nums) + ); + } + + private int robHelper(int start, int end, int[] nums) { + int twoBackMaxAmount = 0, oneBackMaxAmount = 0; + for (int i = start; i < end; i++) { + int maxAmount = Math.max(twoBackMaxAmount + nums[i], oneBackMaxAmount); + + twoBackMaxAmount = oneBackMaxAmount; + oneBackMaxAmount = maxAmount; + } + return oneBackMaxAmount; + } +} +``` From d472ed1b10e34cb2502b9385429e0e5b468d9c14 Mon Sep 17 00:00:00 2001 From: seal_azarashi Date: Wed, 30 Oct 2024 08:09:33 +0900 Subject: [PATCH 4/4] step 4 --- arai60/Dynamic_Programming/house-robber-ii.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arai60/Dynamic_Programming/house-robber-ii.md b/arai60/Dynamic_Programming/house-robber-ii.md index 7ac64cc..772048a 100644 --- a/arai60/Dynamic_Programming/house-robber-ii.md +++ b/arai60/Dynamic_Programming/house-robber-ii.md @@ -87,3 +87,36 @@ class Solution { } } ``` + +## Step 4 + +[oda さんのレビュー](https://github.com/seal-azarashi/leetcode/pull/34#discussion_r1791578173)を踏まえ関数名を修正。 + +```java +class Solution { + public int rob(int[] nums) { + if (nums == null || nums.length == 0) { + return 0; + } + if (nums.length == 1) { + return nums[0]; + } + + return Math.max( + maxRobbableAmountInRange(0, nums.length - 1, nums), + maxRobbableAmountInRange(1, nums.length, nums) + ); + } + + private int maxRobbableAmountInRange(int start, int end, int[] nums) { + int twoBackMaxAmount = 0, oneBackMaxAmount = 0; + for (int i = start; i < end; i++) { + int maxAmount = Math.max(twoBackMaxAmount + nums[i], oneBackMaxAmount); + + twoBackMaxAmount = oneBackMaxAmount; + oneBackMaxAmount = maxAmount; + } + return oneBackMaxAmount; + } +} +```