lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. 题目

 

读题

 https://leetcode.cn/problems/house-robber/

 

考查点

 这道题的考查点是动态规划的基本思想和应用,

  • 即如何将一个复杂的问题分解成更小的子问题,
  • 如何找到问题的状态和状态转移方程,
  • 如何确定问题的边界条件和初始值,
  • 以及如何用代码来实现动态规划的算法。

2. 解法

思路

 一个可能的解决方案是使用一个一维数组dp来存储每个房屋的最大收益,

dp[i]表示从第0个房屋到第i个房屋能够偷窃的最大金额。

那么对于每个房屋,

我们有两种选择:偷或者不偷。

如果我们偷第i个房屋,那么我们不能偷第i-1个房屋,所以dp[i] = dp[i-2] + nums[i]。

如果我们不偷第i个房屋,那么我们可以偷第i-1个房屋,所以dp[i] = dp[i-1]。

我们要取这两种情况的较大值,所以dp[i] = max(dp[i-1], dp[i-2] + nums[i])。

代码逻辑

我可以用以下的步骤来描述代码的逻辑:

  • 首先,我检查输入的数组是否为空或者长度为0,如果是,就直接返回0,因为没有房屋可以偷窃。
  • 其次,我检查输入的数组的长度是否为1,如果是,就直接返回数组的第一个元素,因为只有一间房屋可以偷窃。
  • 然后,我创建一个一维数组dp来存储每个房屋的最大收益,数组的长度和输入的数组相同。我初始化dp[0]为nums[0],dp[1]为nums[0]和nums[1]中的较大值。
  • 接着,我从第2个房屋开始遍历输入的数组,对于每个房屋,我用状态转移方程来更新dp[i],即dp[i] = max(dp[i-1], dp[i-2] + nums[i])。
  • 最后,我返回dp[n-1]作为最终结果,其中n是输入数组的长度。

 

具体实现

 

class Solution {
    public int rob(int[] nums) {
        // 边界条件
        if (nums == null || nums.length == 0) {
            return 0;
        }
        if (nums.length == 1) {
            return nums[0];
        }
        // 创建dp数组
        int n = nums.length;
        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(dp[i-1], dp[i-2] + nums[i]);
        }
        // 返回结果
        return dp[n-1];
    }
}

  3. 总结

posted on 2023-05-01 16:46  白露~  阅读(17)  评论(0编辑  收藏  举报