リコウ-198強盗
1. トピック
198.強盗
あなたは通り沿いの家を盗むことを計画しているプロの泥棒です。各部屋には一定量の現金が隠されています。盗難に影響を与える唯一の制限要因は、隣接する家に相互接続された盗難防止システムが装備されていることです。同じ夜に隣接する 2 つの家が泥棒に侵入された場合、そのシステムは自動的に警察に通報します。
各家に保管されている量を表す非負の整数の配列を指定して、警報を鳴らさずに一晩に盗むことができる最大量を計算します。
例 1:
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
2. 分析
- トピック。このトピックを見て最初に頭に浮かぶのは、それらを隣接させることはできないということです。したがって、それらの一方を盗みたい場合、前のものは盗むことができず、もう一方は盗むことができること
i
i-1
i-2
を考慮する必要があります。おそらく、これが動的計画法の問題であることがわかります。 - 上記の分析によると、dp[i] は現在の i の家を盗むときの最大量です。次に、次の式を推測できます: dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i])。
- 初期化。演繹式によれば、dp の前にある 2 つの数値が必要であることは明らかなので、必要なのは dp[0] と dp[1] です。
- トラバース。2 番目から始めて逆方向に作業します。
3. コードとコメント
class Solution {
public int rob(int[] nums) {
// 1. dp[i]表示到第i个房间能够偷窃的最高金额
if (nums.length == 0) return 0;
if (nums.length == 1) return nums[0];
int[] dp = new int[nums.length + 1];
// 2. 因为递推公式需要dp前两个数,需初始化
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < nums.length; i++){
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[nums.length - 1];
}
}
4. 練習する
トピックへのリンクへのリンク: 198. 強盗