LeetCode213---打家劫舍Ⅱ

題目描述

你是一個專業的小偷,計劃偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味着第一個房屋和最後一個房屋是緊挨着的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。

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

示例1

輸入: [2,3,2]
輸出: 3
解釋: 你不能先偷竊 1 號房屋(金額 = 2),然後偷竊 3 號房屋(金額 = 2, 因爲他們是相鄰的。

示例2

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

解題思路:
使用動態規劃求解

因爲是循環數組,那麼可以分爲兩種情況
1、選擇偷竊第一個房屋,那麼就不能選擇最後一個房屋
2、選擇偷竊最後一個房屋,那麼就不能選擇第一個房屋
3、取兩者最大值

每一種情況都是與 LeetCode198—打家劫舍 的算法思想和編碼過程基本一致

下面爲AC代碼:

class Solution {
public:
    int rob(vector<int>& nums) {
        //核心原則就是,第一個和最後一個不能同時搶,然後選出最大的方案
        if(nums.size() <= 0){
            return 0;
        }
        if(nums.size() == 1){
            return nums[0];
        }
        if(nums.size() == 2){
            return max(nums[0],nums[1]);
        }
        //不搶最後一個房屋
        vector<int> dp1(nums.size() - 1,0);
        dp1[0] = nums[0];
        dp1[1] = max(nums[0],nums[1]);
        for(int i = 2;i < nums.size() - 1;i++){
            dp1[i] = max(dp1[i - 1],dp1[i - 2] + nums[i]);
        }
        //不搶第一個房屋
        vector<int> dp2(nums.size(),0);
        dp2[0] = 0;//表示不搶第一個
        dp2[1] = nums[1];
        for(int i = 2;i < nums.size();i++){
            dp2[i] = max(dp2[i - 1],dp2[i - 2] + nums[i]);
        }
        return max(dp1[nums.size() - 2],dp2[nums.size() - 1]);
    }
};

做完這道題可以試試高級版的 LeetCode337—打家劫舍Ⅲ
高級版的給出的結構是樹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章