力扣 打家劫舍

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

题目

从题可以看出要达到最高金额时,要从相邻的房屋拿。因此是当前房屋的金额隔一个做累加,当然还需要跟前一个相邻的房屋做比较,便于取到哪边金额更高,因此需要一个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;
    }
}

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

相关推荐
wuqingshun314159几秒前
说一下Spring中的ApplicationContext和BeanFactory的区别?
java·后端·spring
wyazyf几秒前
TREA IDE运行java springboot项目
java·spring boot·trea ide 启动java
星月昭铭4 分钟前
一次全表审核“卡99%”故障排查:空字符串在while循环中引发的性能陷阱
java
Q741_1474 分钟前
每日一题 力扣 3548. 等和矩阵分割 II 前缀和 哈希表 C++ 题解
算法·leetcode·前缀和·矩阵·力扣·哈希表
jessecyj5 分钟前
Windows操作系统部署Tomcat详细讲解
java
摇滚侠5 分钟前
Redis 怎么用,Java 开发,Redis 怎么用
java·数据库·redis
木井巳6 分钟前
【递归算法】全排列 Ⅱ
java·算法·leetcode·决策树·深度优先·剪枝
weixin_433179337 分钟前
Python - 调试
java·开发语言·python
Fcy6487 分钟前
算法竞赛有关数据结构的补充(3)—— 二叉树、堆和哈希表的静态实现(包括红黑树和AVL树动态实现)
数据结构·算法·散列表
代码探秘者7 分钟前
【算法篇】6.分治
java·数据结构·后端·python·算法·排序算法