题目: 在一个数组arr中,找出一组不相邻的数字,使得最后的和最大。
思路:
还是老套路, 每个数字都有两种可能, 选和不选, 递归搞定.
但是, 我们会发现递归的时候时间复杂度是呈指数上升的(log2^2),
我们会发现, 很多的子问题, 在普通递归中是被重复计算的, 所以我们需要将每一步的计算结果保存起来, 这样在上层方法利用到下层方法的计算结果时, 可以直接去拿而不需要重复计算, 我们一般使用迭代来实现动态规划算法.
什么是动态规划算法?
题解:
public class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 4, 1, 7, 8, 3};
System.out.println(recur_opt(arr.length - 1, arr));
System.out.println(dp_opt(arr));
}
普通解法:
// 普通迭代
private static int recur_opt(int i, int[] arr) {
if (i == 0) return arr[0];
if (i == 1) return Math.max(arr[0], arr[1]);
// 选i?
int a = recur_opt(i - 2, arr) + arr[i];
// 不选i?
int b = recur_opt(i - 1, arr);
return Math.max(a, b);
}
动态规划算法
// 动态规划
private static int dp_opt(int[] arr) {
// 特殊退出条件
if (arr.length == 1) return arr[0];
if (arr.length == 2) return Math.max(arr[0], arr[1]);
// 保留中间计算结果, 降低复杂度
int[] opt = new int[arr.length];
opt[0] = arr[0];
opt[1] = arr[1];
for (int i = 2; i < opt.length; i++) {
int a = opt[i - 2] + arr[i];
int b = opt[i - 1];
opt[i] = Math.max(a, b);
}
return opt[opt.length-1];
}
}