力扣 打家劫舍

动态规划,当前状态由前两个状态获得,滚动数组。

题目

从题可以看出要达到最高金额时,要从相邻的房屋拿。因此是当前房屋的金额隔一个做累加,当然还需要跟前一个相邻的房屋做比较,便于取到哪边金额更高,因此需要一个dp数组做状态维护。

处理好边界问题,然后列出状态转移方程 dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1])。

时间复杂度: O(n),空间复杂度: O(n)。

java 复制代码
class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int length = nums.length;
        if (length == 1) {
            return nums[0];
        }
        int[] dp = new int[length];
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);
        for (int i = 2; i < length; i++) {
            dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[length - 1];
    }
}

注意,以上做了几次初始化的边界处理,因为直接用 dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]),为了防止数组越界,只能先对前面的数做特殊处理。然后,可以发现这个dp的更新都是与前两个dp有关,优化一下,可以使用滚动数组,在每个时刻只需要存储前两间房屋的最高总金额。这样维护状态的就不是一整个dp数组了,而是前面两个类似前缀和的引用。

时间复杂度: O(n),空间复杂度: O(1)。

java 复制代码
class Solution {
    public int rob(int[] nums) {
        int pre = 0, cur = 0, tmp;
        for(int num : nums) {
            tmp = cur;
            cur = Math.max(pre + num, cur);
            pre = tmp;
        }
        return cur;
    }
}

动态处理的步骤,最重要的就是找到状态转移方程,当前状态可能不做更新,也可能与上一个状态有关。然后注意边界处理,用数组进行状态维护,若只与前几个数有关,也可以做空间优化。

相关推荐
千里马学框架1 小时前
安卓java端service如何在native进程进行访问-跨进程通讯高端知识
android·java·开发语言·安卓framework开发·车机·跨进程·安卓窗口系统
程序研1 小时前
适配器模式
java·设计模式
NULL->NEXT1 小时前
Java(面向对象进阶——接口)
android·java·开发语言
雨 子1 小时前
Spring Boot 日志
java·spring boot·后端·log4j
violin-wang2 小时前
SpringBoot的Bean-高级-第三方Bean以及Bean管理
java·spring boot·后端·bean
梅羽落2 小时前
ideal jdk报错如何解决
java·经验分享·jdk·intellij-idea
多多*2 小时前
Sync底层字节码 monitorEnter和monitorExit 对象监视器
java·开发语言·windows·python·spring
爱掉发的小李2 小时前
JavaWeb简单开发
java·spring·spring cloud·java-ee·tomcat·maven
缘友一世2 小时前
Java 8 Stream API
java
计算机学姐2 小时前
基于SpringBoot的健身房管理系统
java·vue.js·spring boot·后端·mysql·spring·mybatis