您的位置:首页 > 其它

lintcode打劫房屋

2016-11-27 00:01 204 查看
原题地址

题目:

假设你是一个专业的窃贼,准备沿着一条街打劫房屋。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警。

给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,你最多可以得到多少钱 在不触动报警装置的情况下。

您在真实的面试中是否遇到过这个题? Yes

样例

给定 [3, 8, 4], 返回 8.

分析:

简单dp题。当前房屋 i 的最大可达钱取决于dp[i - 2]和dp[i - 3]的最大值(dp[i - 4]的情况属于dp[i - 2])。

注意返回值要为long型。

时间复杂度o(n),空间o(n)

public long houseRobber(int[] A) {
long[] dp = new long[A.length];
if (A.length < 1) {
return 0;
}
if (A.length == 1) return A[0];
dp[0] = A[0];
dp[1] = A[1];
long max = Math.max(dp[0], dp[1]);
if (A.length <= 2) {
return max;
}
dp[2] = dp[0] + A[2];
if (dp[2] > max) max = dp[2];
for (int i = 3; i < A.length; i++) {
dp[i] = (dp[i - 2] > dp[i - 3] ? dp[i - 2] : dp[i - 3]) + A[i];
if (dp[i] > max) {
max = dp[i];
}
}
return max;
}


改进的时间复杂度o(n),空间o(1),用dp1和dp2保存dp[i - 3]和dp[i - 2]。

public long houseRobber(int[] A) {
if (A.length < 1) {
return 0;
}
if (A.length < 2) {
return A[0];
}
long dp1 = A[0];
long dp2 = A[1];
long max = Math.max(dp1, dp2);
if (A.length == 2) {
return max;
}
max = (dp1 + A[2]) > dp2 ? (dp1 + A[2]) : dp2;
long temp = max;
long tempLast = temp;
for (int i = 3; i < A.length; i++) {
temp = (dp1 > dp2 ? dp1 : dp2) + A[i];
if(temp > max) max = temp;
dp1 = dp2;
dp2 = tempLast;
tempLast = temp;
}
return max;
}


另外一种思路

参考网址

用一个二维数组dp[A.length][2],其中对于第i所房子,dp[i][0]表示不打劫i,此时其能获得的最大钱数为:

dp[i][0] = max(dp[i - 1][0] ,dp[i - 1][1])

dp[i][1]表示打劫i,其等于不打劫上一家的情况下,再加上i的钱数:

dp[i][1] = dp[i - 1][0] + A[i];

public long houseRobber(int[] A) {
if(A.length==0)
return 0;
long[][] dp = new long[A.length][2];
dp[0][1] = A[0];
for(int i=1;i<A.length;++i){
dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]);
dp[i][1] = dp[i-1][0]+A[i];
}
return Math.max(dp[A.length-1][0],dp[A.length-1][1]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: