【LeetCode】打家劫舍 II [M](动态规划)

166 篇文章 0 订阅

213. 打家劫舍 II - 力扣(LeetCode)

一、题目

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。

给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。

示例 1:

输入:nums = [2,3,2]
输出:3
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。

示例 2:
输入:nums = [1,2,3,1]
输出:4
解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。

示例 3:​​​​​​​

输入:nums = [1,2,3]
输出:3

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 1000

二、代码

class Solution {
    public int rob(int[] nums) {
        // 过滤无效参数
        if (nums == null || nums.length == 0) {
            return 0;
        }
        // 单独讨论特殊情况
        if (nums.length == 1) {
            return nums[0];
        } else if (nums.length == 2) {
            return Math.max(nums[0], nums[1]);
        }
        // 数组长度
        int n = nums.length;
        // dp[i]:表示到i为止的符合条件的最大累加和
        int[] dp = new int[n];

        // 因为数组是一个环,所以0位置和n-1位置是连在一起的,所以0位置额和n-1位置一定不能同时选择,所以就分两种情况

        // 情况一:从0位置开始选择,0~n-2范围上进行选择
        dp[0] = nums[0];
        // 这里要取0位置和1位置的最大值给dp[1]赋值
        dp[1] = Math.max(nums[0], nums[1]);
        // 构造dp数组
        for (int i = 2; i < n - 1; i++) {
            // 一共三种情况
            // 1、只选i位置
            // 2、不选i位置,只从0~i-1位置自由选择,即dp[i - 1]
            // 3、选择i位置,然后从0~i-2位置自由选择,即dp[i - 2] + nums[i]
            // 这三种情况可以保证完全没有选择相邻位置的情况
            dp[i] = Math.max(nums[i], Math.max(dp[i - 1], dp[i - 2] + nums[i]));
        }

        int max = dp[n - 2];
        // 情况二:从1位置开始选择,1~n-1范围上进行选择
        dp[1] = nums[1];
        // 这里要取1位置和2位置的最大值给dp[2]赋值
        dp[2] = Math.max(nums[1], nums[2]);
        // 构造dp数组
        for (int i = 3; i < n; i++) {
            // 一共三种情况
            // 1、只选i位置
            // 2、不选i位置,只从1~i-1位置自由选择,即dp[i - 1]
            // 3、选择i位置,然后从1~i-2位置自由选择,即dp[i - 2] + nums[i]
            // 这三种情况可以保证完全没有选择相邻位置的情况
            dp[i] = Math.max(nums[i], Math.max(dp[i - 1], dp[i - 2] + nums[i]));
        }
        // 选择两种情况的最大值进行返回
        max = Math.max(max, dp[n - 1]);
        return max;
    }
}

三、解题思路 

和打家劫舍Ⅰ的区别就是这里给的是一个环形数组,本质就是求选择不相邻的子序列的最大累加和。

两种情况,因为0位置和N-1位置一定不可能同时都选,所以就有两种情况,一种只选0位置,一种只选N-1位置。

1)选0位置,也就是求0~N-2范围上的最优解

2)不选0位置,选N-1位置,也就是求1~N-1范围上的最优解

两种可能性中,求max。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值