213. House Robber II

 
 
Total Accepted: 24216 Total Submissions: 80632 Difficulty: Medium

Note: This is an extension of House Robber.

After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.

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.

Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

这个题目是基于House Robber I 的,所以做这题之前要先知道HouseRobber I的解法。

House Robber I 的传送门:

House Robber I

如果已经ac了第一题,那么这题的意思就是把屋子都改成环状。

在第一题中,dp状态转移方程    max[ i ] = Math.max( max[ i - 1 ], nums[ i - 1 ] + max[ i - 2 ] ) 已经做出来了。那么第二题就很好做了。

第二题中,我的做法就是要再进行一次dp,并且需要记录下选择屋子的首尾,记为start和last.

在记录start的时候,要注意start的状态 : 1.当前面的屋子已经被选择。2.当前面的屋子没有被选择。

所以这里的dp转移方程总结为:

            if( max[ i - 1 ] > nums[ i - 1 ] + max[ i - 2 ] ) {
max[ i ] = max[ i - 1 ];
start[ i ] = start[ i - 1 ];
} else {
max[ i ] = nums[ i - 1 ] + max[ i - 2 ];
last = i;
if( max[ i - 1 ] == max[ i - 2 ] ) {
start[ i ] = start[ i - 2 ];
} else {
start[ i ] = start[ i - 2 ] == 0 ? 2 : start[ i - 2 ];
}
}

最后判断一下,如果是选择最后一个的时候报警了,进行判断是要选择(1,n)还是(0,n-1)的最大价值

总的思想就是进行两次DP,(1,n)和(0,n-1)分别Dp

Ps:暂时没有想到更好更加简洁的方法。不过我觉得是有的,只是本人愚笨没想到

public class Solution {

    public int rob( int[] nums ) {

        int[] max = new int[ nums.length + 1 ];
int[] start = new int[ nums.length + 1 ];
max[ 0 ] = 0;
start[ 0 ] = 0;
if( nums == null || nums.length == 0 )
return 0;
max[ 1 ] = nums[ 0 ];
start[ 1 ] = 1;
int last = 1;
for( int i = 2; i <= nums.length; i++ ) {
if( max[ i - 1 ] > nums[ i - 1 ] + max[ i - 2 ] ) {
max[ i ] = max[ i - 1 ];
start[ i ] = start[ i - 1 ];
} else {
max[ i ] = nums[ i - 1 ] + max[ i - 2 ];
last = i;
if( max[ i - 1 ] == max[ i - 2 ] ) {
start[ i ] = start[ i - 2 ];
} else {
start[ i ] = start[ i - 2 ] == 0 ? 2 : start[ i - 2 ];
}
}
}
if( ( last + 1 ) % nums.length == start[ nums.length ] ) {
int[] tail = new int[nums.length-1];
System.arraycopy( nums, 1, tail, 0, nums.length-1 );
int preMax = rob2( tail );
max[ nums.length ] = Math.max( ( max[ nums.length ] - max[ 1 ] ), max[ nums.length - 1 ] );
max[ nums.length ] = Math.max( max[ nums.length ], preMax );
}
return max[ nums.length ];
} public int rob2( int[] nums ) { int[] max = new int[ nums.length + 1 ];
max[ 0 ] = 0;
if( nums == null || nums.length == 0 )
return 0;
max[ 1 ] = nums[ 0 ];
for( int i = 2; i <= nums.length; i++ ) {
max[ i ] = Math.max( max[ i - 1 ], nums[ i - 1 ] + max[ i - 2 ] );
}
return max[ nums.length ];
} public static void main( String[] args ) {
Solution s = new Solution();
int[] nums = new int[] { 2, 2, 4, 3, 2, 5 };
System.out.println( s.rob( nums ) );
} }

[LeetCode]House Robber II (二次dp)的更多相关文章

  1. [LeetCode] House Robber II 打家劫舍之二

    Note: This is an extension of House Robber. After robbing those houses on that street, the thief has ...

  2. Leetcode House Robber II

    本题和House Robber差不多,分成两种情况来解决.第一家是不是偷了,如果偷了,那么最后一家肯定不能偷. class Solution(object): def rob(self, nums): ...

  3. [LintCode] House Robber II 打家劫舍之二

    After robbing those houses on that street, the thief has found himself a new place for his thievery ...

  4. [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列

    A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...

  5. [LeetCode] Paint House II 粉刷房子之二

    There are a row of n houses, each house can be painted with one of the k colors. The cost of paintin ...

  6. [LeetCode] Palindrome Partitioning II 拆分回文串之二

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  7. LeetCode之“动态规划”:House Robber && House Robber II

    House Robber题目链接 House Robber II题目链接 1. House Robber 题目要求: You are a professional robber planning to ...

  8. leetcode 198. House Robber 、 213. House Robber II 、337. House Robber III 、256. Paint House(lintcode 515) 、265. Paint House II(lintcode 516) 、276. Paint Fence(lintcode 514)

    House Robber:不能相邻,求能获得的最大值 House Robber II:不能相邻且第一个和最后一个不能同时取,求能获得的最大值 House Robber III:二叉树下的不能相邻,求能 ...

  9. 【刷题-LeetCode】213. House Robber II

    House Robber II You are a professional robber planning to rob houses along a street. Each house has ...

随机推荐

  1. 给 Memo 排序的函数

    本例效果图: 代码文件: unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, ...

  2. jQuery中animate动画第二次点击事件没反应

    jQuery中animate动画第二次点击事件没反应 用animate做点击翻页动画时发现第二次点击事件动画没反应,而第一次点击有动画效果,代码如下: 复制代码 代码如下: $(".page ...

  3. JDK中的插入排序

    算法 有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法--插入排序法,插入排序的基本操作就是将一个数据插入到已经排好 ...

  4. C# 启动停止SQLServer数据库服务器

    C#启动停止SQL数据库服务方法之一: 在命令行里填写命令:net start/stop mssqlserver C#启动停止SQL数据库服务方法之二: 通过C#代码实现: class Program ...

  5. HTML5画布(CANVAS)速查简表

    HTML5画布(CANVAS)速查简表 http://www.webhek.com/misc/html5-canvas-cheat-sheet/

  6. 分享一个基于thrift的java-rpc框架

    简单介绍 这是一个简单小巧的Java RPC框架,适用于Java平台内.为系统之间的交互提供了.高性能.低延迟的方案.适合在集群数量偏少的情况下使用(50台以下集群环境).当然.它也可以在大型集群环境 ...

  7. Docker环境中部署OwnCloud 9.0

    整体思路: 1.官方获取mysql.php+apache镜像: 2.基于php+apache,创建OwnCloud镜像: 3.启动mysql镜像: 4.启动OwnCloud镜像,链接mysql镜像,访 ...

  8. mac bash_profile

    # This is the filename where your incoming mail arrives. MAIL=~/mbox MAILCHECK=30 HISTFILE=~/.histor ...

  9. Redis系列三(redis配置文件分析)

    在第一篇文章中有提到过redis.conf这个文件,这个文件就是redis-server的具体配置了.要使用好redis,一定要搞清楚redis的配置文件,这样才能最大的发挥redis的性能. # B ...

  10. ADXL345经验总结,采用SPI和I2C总线操作

    一. ADXL345简介       ADXL345是ADI公司推出的三轴(x,y,z)iMEMS数字加速度计(digital accelerometer),具有在16G下高分辨率(13Bit)测量能 ...