力扣 打家劫舍

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

题目

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

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

相关推荐
BillKu11 分钟前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis
全栈凯哥11 分钟前
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
java·算法·leetcode·链表
chxii12 分钟前
12.7Swing控件6 JList
java
全栈凯哥14 分钟前
Java详解LeetCode 热题 100(27):LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)详解
java·算法·leetcode·链表
YuTaoShao14 分钟前
Java八股文——集合「List篇」
java·开发语言·list
SuperCandyXu18 分钟前
leetcode2368. 受限条件下可到达节点的数目-medium
数据结构·c++·算法·leetcode
PypYCCcccCc19 分钟前
支付系统架构图
java·网络·金融·系统架构
Humbunklung35 分钟前
机器学习算法分类
算法·机器学习·分类
华科云商xiao徐41 分钟前
Java HttpClient实现简单网络爬虫
java·爬虫
Ai多利44 分钟前
深度学习登上Nature子刊!特征选择创新思路
人工智能·算法·计算机视觉·多模态·特征选择