目次
トピックのソース
トピックの説明
あなたはプロの泥棒で、通り沿いの家々に強盗を計画しています。各家には一定量の現金が隠されています。この場所の家はすべて円状に配置されており、最初の家と最後の家がすぐ隣り合っていることを意味します。同時に、隣接する家には相互接続された盗難防止システムが装備されており、同じ夜に隣接する2つの家に泥棒が侵入した場合、システムが自動的に警察に通報します。
各家に保管されているお金の量を表す負でない整数の配列が与えられた場合、警報を鳴らさずに今夜盗むことができる最大金額を計算します。
例
例 1:
入力: nums = [2,3,2]
出力: 3
説明: 家 1 (金額 = 2) を盗み、次に家 3 (金額 = 2) を盗むことはできません。これらは隣接しているためです。
例 2:
入力: nums = [1,2,3,1]
出力: 4
説明: 最初に家 1 (金額 = 1) を盗み、次に家 3 (金額 = 3) を盗むことができます。盗まれた最大量 = 1 + 3 = 4。
例 3:
入力: nums = [1,2,3]
出力: 3
ヒント
- 1 <= nums.length <= 100
- 0 <= nums[i] <= 1000
トピック分析
この質問はLeetCode - 198 強盗 - 府城市外のブログ - CSDN ブログ拡張機能の質問です
この質問をする前に、まずリンクのトピックを理解する必要があります。
この質問とリンクされた質問の違いは、198 Dajiajieshe は線形配列であるのに対し、213 Dajiajieshe は円形配列であることです。
線形配列 nums[0] が選択されていますが、nums[nums.length-1] の選択には影響しません。
リング配列の場合、nums[0]を選択した場合、nums[0]とnums[nums.length-1]は隣接しているため、nums[nums.length-1]は選択できません。
したがって、この質問を行う最も簡単な方法は、リング配列を最初から最後まで解き、線形配列に変えることです。
つまり、円形アレイは 2 種類の線形アレイに分割できます。
- nums[0] を破棄し、残りは線形配列を形成します
- nums[nums.length - 1] を破棄し、残りの部分は線形配列を形成します
したがって、この質問は、円形配列が線形配列に分割され、線形配列は 198 に従って直接実行できる 198 と比較して、さらに 1 つのステップにすぎません。
JSアルゴリズムのソースコード
/**
* @param {number[]} nums
* @return {number}
*/
var rob = function (nums) {
if (nums.length == 1) return nums[0];
return Math.max(
stealMaxMoney(nums.slice(0, -1)),
stealMaxMoney(nums.slice(1))
);
};
function stealMaxMoney(nums) {
const n = nums.length;
const dp = new Array(n);
if (n >= 1) dp[0] = nums[0];
if (n >= 2) dp[1] = Math.max(nums[0], nums[1]);
for (let i = 2; i < n; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[n - 1];
}
Javaアルゴリズムのソースコード
class Solution {
public int rob(int[] nums) {
if(nums.length == 1) return nums[0];
return Math.max(stealMaxMoney(Arrays.copyOfRange(nums, 0, nums.length - 1)), stealMaxMoney(Arrays.copyOfRange(nums, 1, nums.length)));
}
public int stealMaxMoney(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
if (n >= 1) dp[0] = nums[0];
if (n >= 2) dp[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < n; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[n - 1];
}
}
Pythonアルゴリズムのソースコード
def stealMaxMoney(nums):
n = len(nums)
dp = [0] * n
if n >= 1:
dp[0] = nums[0]
if n >= 2:
dp[1] = max(nums[0], nums[1])
for i in range(2, n):
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
return dp[n - 1]
class Solution(object):
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 1:
return nums[0]
return max(stealMaxMoney(nums[:-1]), stealMaxMoney(nums[1:]))