【33】打家劫舍II

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/house-robber-ii/

題目

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

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

示例 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 = [0]
輸出:0

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 1000

思路

參考leecode的題解,我們使用動態(tài)規(guī)劃的思路來解決。

根據(jù)題意,收尾數(shù)組不能同時偷,否則會觸發(fā)警報,那么可以將數(shù)組分為兩段,分別求出可收獲的最大金額,取最高的即可。

這里需要考慮特殊情況:

  1. 如果只有一家房屋,那直接偷就完事,renturn nums[0];
  2. 如果有兩件房屋,直接偷金額最多的屋子,return max(nums[0], nums[1]);
  3. 如果房屋數(shù)多于兩間,那么就可以分段,計算(0, n - 2)范圍的金額和(1, n - 1)范圍的金額,取最高的即可。

代碼

    public int rob(int[] nums) {
        int n = nums.length;
        if (nums.length == 1) {
            return nums[0];
        } else if (nums.length == 2) {
            return Math.max(nums[0], nums[1]);
        } else {
            return Math.max(robRange(nums, 0, n - 2), robRange(nums, 1, n - 1));
        }
    }

    /**
        分而治之:在確定的范圍內(nèi)使用動態(tài)規(guī)劃思路
    */
    private static int robRange(int[] nums, int start, int end) {
        int first = nums[start];
        int second = Math.max(nums[start], nums[start + 1]);
        int ret = 0;
        for (int i = start + 2; i <= end; i++) {
            int temp = second;
            second = Math.max(first + nums[i], second);
            first = temp;
        }
        return second;
    }

結(jié)果

執(zhí)行結(jié)果
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容