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. 浅谈Log4j

    1 什么是Log4j Log4j 是Apache为Java提供的日志管理工具.为了你快速理解Log4j的作用,我们用下面的代码说明Log4j的作用.我们为了调试程序,总是需要在程序使用System.o ...

  2. 在向服务器发送请求时发生传输级错误。 (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接。)

    用VS2005+SQLSERVER2008开发C/S的程序,程序上线运行一段时间之后发现在某些功能偶尔出现如下的错误: 在向服务器发送请求时发生传输级错误. (provider: TCP 提供程序, ...

  3. jquery.cookie实战用法详细解析

    Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是 ...

  4. java解析XML,并生成文档

    一.Java中XML的四种方法 Java学习者须知:Java中XML的四种方法 java xml学习总结(4中方法的例子介绍) JDOM解析XML Dom4j解析XML

  5. Express 3.0新手指南入门教程

    在确认已经安装了node之后(下载), 在你的机器上创建一个目录,让我们来开始你的第一个应用程序吧 $ mkdir hello-world 在这个目录中你首先得定义一下你的应用程序“包”文件,它和其它 ...

  6. 关于GCD同步组实现多个异步线程的同步执行中的注意点

    在App开发中经常会遇到多个线程同时向服务器取数据, 如果每个线程取得数据后都去刷新UI会造成界面的闪烁 也有可能出现部分数据还没有获取完毕造成程序crash 之前在网上看到很多是利用dispatch ...

  7. Vmware 中安装 Ubuntu Server (或者ubuntu 以文本界面登陆时) 分辨率无法全屏问题

    Vmware 中安装 Ubuntu Server/Ubuntu 分辨率,无法全屏问题 需要更改grub设置 在终端或者文本界面按下列步骤进行设置: 第一步: 输入命令 sudo vim /etc/de ...

  8. 安装Oracle服务端后配置注册表与PL/SQL

    1.流程: 1.安装Oracle客户端(绿色版和安装版均可,建议安装在和Oracle服务端文件夹并行的路径下,例:E:\app\yginuo\product\11.2.0) 2.配置环境变量和注册表( ...

  9. FZU 2167 大王叫我来巡山呐

    Problem 2167 大王叫我来巡山呐 Accept: 931    Submit: 1405Time Limit: 1000 mSec    Memory Limit : 32768 KB Pr ...

  10. C# GDI绘图之——画笔和画刷

    绘制图形需要画笔和画刷: Pen(画笔类): Pen为C#编程语言中专门的画笔类 使用方式: // 用系统颜色来初始化我们的画笔类,使用Color静态类中的颜色 1. Pen p1 = new Pen ...