|
|
package class04;
|
|
|
|
|
|
// 在线测试链接 : https://leetcode.com/problems/house-robber/
|
|
|
public class Code04_SubArrayMaxSumFollowUp {
|
|
|
|
|
|
public static int rob1(int[] arr) {
|
|
|
if (arr == null || arr.length == 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
if (arr.length == 1) {
|
|
|
return arr[0];
|
|
|
}
|
|
|
int[] dp = new int[arr.length];
|
|
|
// dp[i] : arr[0..i]挑选,满足不相邻设定的情况下,随意挑选,最大的累加和
|
|
|
dp[0] = arr[0];
|
|
|
dp[1] = Math.max(arr[0], arr[1]);
|
|
|
for (int i = 2; i < arr.length; i++) {
|
|
|
int p1 = dp[i - 1];
|
|
|
int p2 = arr[i] + Math.max(dp[i - 2], 0);
|
|
|
dp[i] = Math.max(p1, p2);
|
|
|
}
|
|
|
return dp[arr.length - 1];
|
|
|
}
|
|
|
|
|
|
// 给定一个数组arr,在不能取相邻数的情况下,返回所有组合中的最大累加和
|
|
|
// 思路:
|
|
|
// 定义dp[i] : 表示arr[0...i]范围上,在不能取相邻数的情况下,返回所有组合中的最大累加和
|
|
|
// 在arr[0...i]范围上,在不能取相邻数的情况下,得到的最大累加和,可能性分类:
|
|
|
// 可能性 1) 选出的组合,不包含arr[i]。那么dp[i] = dp[i-1]
|
|
|
// 比如,arr[0...i] = {3,4,-4},最大累加和是不包含i位置数的时候
|
|
|
//
|
|
|
// 可能性 2) 选出的组合,只包含arr[i]。那么dp[i] = arr[i]
|
|
|
// 比如,arr[0...i] = {-3,-4,4},最大累加和是只包含i位置数的时候
|
|
|
//
|
|
|
// 可能性 3) 选出的组合,包含arr[i], 且包含arr[0...i-2]范围上的累加和。那么dp[i] = arr[i] + dp[i-2]
|
|
|
// 比如,arr[0...i] = {3,1,4},最大累加和是3和4组成的7,因为相邻不能选,所以i-1位置的数要跳过
|
|
|
//
|
|
|
// 综上所述:dp[i] = Max { dp[i-1], arr[i] , arr[i] + dp[i-2] }
|
|
|
public static int rob2(int[] arr) {
|
|
|
if (arr == null || arr.length == 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
int N = arr.length;
|
|
|
if (N == 1) {
|
|
|
return arr[0];
|
|
|
}
|
|
|
if (N == 2) {
|
|
|
return Math.max(arr[0], arr[1]);
|
|
|
}
|
|
|
int[] dp = new int[N];
|
|
|
dp[0] = arr[0];
|
|
|
dp[1] = Math.max(arr[0], arr[1]);
|
|
|
for (int i = 2; i < N; i++) {
|
|
|
dp[i] = Math.max(Math.max(dp[i - 1], arr[i]), arr[i] + dp[i - 2]);
|
|
|
}
|
|
|
return dp[N - 1];
|
|
|
}
|
|
|
|
|
|
}
|