LeetCode198. 打家劫舍

 

思路:状态的定义很重要。

状态定义1:  dp[i]表示 到第 i 个房子的最大金额

class Solution {
    /**
     *  dp[n]表示 到第n个房子的最大金额
     *      1.如果偷第n个房子,由于不能相邻,dp[n]= dp[n-2] + nums[n]
     *      2.如果不偷第n个房子,那么dp[n] = dp[n-1] (即等于到第n-1个房子的最大金额)
     */
    public int rob(int[] nums) {
        int n = nums.length;
        if (n == 0) return 0;
        if (n == 1) return nums[0];

        int[] dp = new int[n];
        dp[0] = nums[0];  // 只有一间房子,直接偷
        dp[1] = Math.max(nums[0], nums[1]); // 只有两间房子,偷金额高的那个
        for (int i = 2; i < n; i++) {
            dp[i] = Math.max(nums[i] + dp[i-2], dp[i-1]);
        }
        return dp[n-1];
        /**
         *  优化空间复杂度为 O(1)。  由于 i 只依赖 i-1 和 i-2 两个状态
         */
        /*
        int a = nums[0]; // a 表示 i-2
        int b = Math.max(nums[0], nums[1]); // b 表示 i-1
        for (int i = 2; i < n; i++) {
            int temp = Math.max(nums[i] + a, b);
            a = b;
            b = temp;
        }
        return b;
        */
    }
}

 

状态定义2: dp[i] 表示 从前 i 个房子能偷到的最大金额

class Solution {
    public int rob(int[] nums) {
        int n = nums.length;
        if (n == 0) return 0;
        if (n == 1) return nums[0];

        // dp[i] 表示 从前 i 个房子能偷到的最大金额
        int[] dp = new int[n + 1];
        dp[0] = 0;
        dp[1] = nums[0];
        for (int i = 2; i <= n; i++) {
            dp[i] = Math.max(nums[i-1] + dp[i-2], dp[i-1]);
        }
        return dp[n];
    }
}

 

posted @ 2021-01-02 16:48  不学无墅_NKer  阅读(115)  评论(0编辑  收藏  举报