记忆化搜索
递归的过程中有许多的结果是被反复计算的,这样会大大降低算法的执行效率。
将已经计算出来的结果保存起来,计算用到的时候直接取出结果,避免重复运算,因此极大的提高了算法的效率。
力扣509斐波那契数
F(n)=F(n−1)+F(n−2)
class Solution {
public int fib(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
int[] memory = new int[n + 1];
memory[0] = 0;
memory[1] = 1;
for (int i = 2; i < memory.length; i++) {
memory[i] = -1;
}
return dfs(memory, n);
}
private int dfs(int[] memory, int n) {
if (n == 0) return 0;
if (n == 1) return 1;
int partI;
int partII;
partI = memory[n - 2] == -1 ? memory[n - 2] = dfs(memory, n - 2) : memory[n - 2];
partII = memory[n - 1] == -1 ? memory[n - 1] = dfs(memory, n - 1) : memory[n - 1];
return partI + partII;
}
}
力扣322零钱兑换
为了避免重复的计算,我们将每个递归的答案存在一个数组中进行记忆化,
如果下次还要计算这个问题的值直接从数组中取出返回即可
public class Solution {
public int coinChange(int[] coins, int amount) {
if (amount < 1) {
return 0;
}
return coinChange(coins, amount, new int[amount]);
}
private int coinChange(int[] coins, int rem, int[] count) {
if (rem < 0) {
return -1;
}
if (rem == 0) {
return 0;
}
if (count[rem - 1] != 0) {
return count[rem - 1];
}
int min = Integer.MAX_VALUE;
for (int coin : coins) {
int res = coinChange(coins, rem - coin, count);
if (res >= 0 && res < min) {
min = 1 + res;
}
}
count[rem - 1] = (min == Integer.MAX_VALUE) ? -1 : min;
return count[rem - 1];
}
}