力扣 打家劫舍

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

题目

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

处理好边界问题,然后列出状态转移方程 dpi = Math.max(dpi - 2 + numsi, dpi - 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];
    }
}

注意,以上做了几次初始化的边界处理,因为直接用 dpi = Math.max(dpi - 2 + numsi, dpi - 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;
    }
}

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

相关推荐
我命由我123459 小时前
执行 Gradle 指令报错,无法将“grep”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
考虑考虑9 小时前
Sentinel安装
java·后端·微服务
轻颂呀9 小时前
约瑟夫环问题
算法
凤凰院凶涛QAQ11 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
科技大视界11 小时前
投资AI项目,传统尽调不够用了——李章虎律师拆解算法、数据、算力三大雷区
人工智能·算法·数据挖掘
郝学胜-神的一滴11 小时前
算法实战:最小k个数——大顶堆的优雅解法
开发语言·数据结构·c++·python·程序人生·算法·排序算法
Irissgwe12 小时前
算法滑动窗口
数据结构·算法
掘金_答案12 小时前
上线那天,一个 ConcurrentHashMap 差点送走我的 AI 客服——3 天排查 JVM 血泪史
java·后端·架构
怪兽学LLM12 小时前
LeetCode 105. 从前序与中序遍历序列构造二叉树:分治递归思路详解
算法·leetcode·职场和发展
可编程芯片开发12 小时前
基于PI控制的三相整流器控制系统的simulink建模与仿真,包含超级电容充电和电机
算法