1. 程式人生 > 其它 >演算法之字串字元統計

演算法之字串字元統計

198. 打家劫舍

題目連結:198. 打家劫舍(中等)

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

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

示例 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 。

提示:

  • 1 <= nums.length <= 100

  • 0 <= nums[i] <= 400

解題思路

經典動態規劃問題,運用動態規劃五部曲解決,具體在程式碼中有標註。

C++

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        if (nums.size() == 1) return nums[0];
        // 1. dp[i] 表示在下標i以內(包括i)的房間,可以偷盜的最大金額
vector<int> dp(nums.size(), 0); // 3. 初始化dp陣列 // 從遞推公式來看,只能從下標為 2 的房間開始考慮,即需要初始化dp[0]和dp[1] // dp[0] 只有一個選擇,那就是偷,所以dp[0]初始化為nums[0] // dp[1] 有兩個選擇,要麼是偷0號房間,要麼偷1號房間,就看那個房間的錢多 dp[0] = nums[0]; dp[1] = max(nums[0], nums[1]); // 4. 遍歷順序:從前往後 for
(int i = 2; i < nums.size(); i++) { // 2. 遞推公式 // 對於第 i 號房間,要麼選擇偷,要麼選擇不偷 // 如果選擇偷,那麼第 i - 1 號房間就不能偷,所以與第 i - 2 號房間有關 // 如果選擇不偷,那麼第 i - 1 號房間就能偷,所以與第 i - 1 號房間有關 dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]); } // 5.列印dp陣列(略) return dp[nums.size() - 1]; } };

JavaScript

/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
    if (nums.length === 0) return 0;
    if (nums.length === 1) return nums[0];
    const dp = new Array(nums.length).fill(0);
    dp[0] = nums[0];
    dp[1] = Math.max(nums[0], nums[1]);
    for (let i = 2; i < nums.length; i++) {
        dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
    }
    return dp[nums.length - 1];
};