Leetcode - 213. House Robber II

URL: https://leetcode.com/problems/house-robber-ii/

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Example 1:

Input: [2,3,2]
Output: 3
Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2),
             because they are adjacent houses.

Example 2:

Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
             Total amount you can rob = 1 + 3 = 4.

 

解决方案:

Since it is a cyclied array, to make our dynamic programming alogrithm works, we need to break the cyclied array into two single-way arrays.

2-The priciple here is that either a particular house i-th can be robbed or not robbed at all.

For example 1 -> 3 -> 6 -> 5, we can break at the first position, so that the problem is divided to two parts,which are 1 -> 3 -> 6 (we choose to rob the first element, but not the last one.) and 3->6->5. Finally, we can reuse the House Robber I to solve these two sub-problems and pick out the optimal solution.

3-Here some of us may have the confusion that: we can rob house 1, it does not mean that we must rob house 1, whether we rob house 1 is depending on its next value. The correct complement of this statement is that: we should not(must not) rob house 1 ( and similarly, whether to rob the last house depends on the whole broken array.)

复制代码
class Solution {
    public int rob(int[] nums) {
        if(nums == null || nums.length == 0) return 0;
        
        if(nums.length == 1) return nums[0];
        
        int len = nums.length; 
        int[] amount = new int[len];
        //The first case: we can rob house 1, definitely, we cannot rob the last one
        amount[0] = nums[0];
        // whether we rob house 1 is depending the relative value 
        amount[1] = Math.max(nums[0],nums[1]);
        for(int idx =2; idx < len-1; idx ++){
            amount[idx] = Math.max(amount[idx-1],amount[idx-2] + nums[idx]);
        }
        // the last element is zero. amount[len-1] by default is zero  
        int totalSumCaseOne = amount[len-2];
        
        // The second case: we don't rob house 1 at all. 
        amount = new int[len];
        amount[0] = 0;
        amount[1] = nums[1];
        for(int idx = 2 ;idx< len; idx++){
            amount[idx] = Math.max(amount[idx-1],amount[idx-2] + nums[idx]);
        }
        int totalSumCaseTwo = amount[len-1];

        //select the largest one 
        return Math.max(totalSumCaseOne,totalSumCaseTwo);
    }
}
复制代码

 

posted on   frank_cui  阅读(102)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

levels of contents
点击右上角即可分享
微信分享提示