1. 程式人生 > >Leetcode題解之動態規劃(4)最大子序和打家劫舍

Leetcode題解之動態規劃(4)最大子序和打家劫舍

題目:https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/23/dynamic-programming/57/

題目描述:

打家劫舍

你是一個專業的小偷,計劃偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警

給定一個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。

示例 1:

輸入: [1,2,3,1]
輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) ,然後偷竊 3 號房屋 (金額 = 3)。
     偷竊到的最高金額 = 1 + 3 = 4 。

示例 2:

輸入: [2,7,9,3,1]
輸出: 12
解釋: 偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9),接著偷竊 5 號房屋 (金額 = 1)。
     偷竊到的最高金額 = 2 + 9 + 1 = 12 。

思路: 動態規劃。用dp[]表示每次到一個房子時能獲得的最大金額。可以推出第一間房子是,dp[0]=num[0],第二間房子時,dp[1]=max(num[0],num[1]) 。之後都有動態規劃方程:dp[i] = Math.max(sum[i-2]+a[i],sum[i-1])。

注意:這裡dp[]記錄的是到此位置所能獲得的最大收益。也就是說在其他位置停止有可能獲得更大的金額。所以需要比較在那個房子時的金額最大。

程式碼:

class Solution {
    public int rob(int[] nums) {
        int len = nums.length;
        if(len==0)
            return 0;
        if(len==1)
            return nums[0];
      
        int[] dp = new int[len];
        int sum=0;
        dp[0]=nums[0];
        dp[1]=Math.max(nums[0],nums[1]);
        for(int i=2;i<len;i++){
            dp[i]=Math.max(nums[i]+dp[i-2],dp[i-1]);
        }
        int k=0;
        for(int i=0;i<len;i++){
           if(dp[i]>dp[k]){
               dp[k]=dp[i];
           }
        }
        return dp[k];
    }
}