355 字
2 分钟
动态规划解题思路
动态规划解题思路
斐波那契数列
暴力递归
// f(n) 计算第 n 个斐波那契数 static int fib(int n) { if(n <= 1 && n >= 0) { return n; } return fib(n - 1) + fib(n - 2); }
使用Memo数组存储,避免重复计算
static long fib2(int n) { long[] memo = new long[n + 1]; Arrays.fill(memo,-1); return dp(memo,n);
} static long dp(long[] memo,int n) { if(n == 0 || n == 1) { return n; } if(memo[n] != -1) { return memo[n]; } memo[n] = dp(memo,n - 1) + dp(memo,n - 2); return memo[n]; }
零钱兑换
class Solution { public int coinChange(int[] coins, int amount) { int[] dp = new int[amount + 1]; Arrays.fill(dp,amount + 1); dp[0] = 0; for(int i = 0;i<dp.length;i++) { for(int coin : coins) { if(i - coin < 0) { continue; } dp[i] = Math.min(dp[i],1 + dp[i - coin]); } } return (dp[amount] == amount + 1) ? -1 : dp[amount]; }}
class Solution { int[] memo;
public int coinChange(int[] coins, int amount) { memo = new int[amount + 1]; // 备忘录初始化为一个不会被取到的特殊值,代表还未被计算 Arrays.fill(memo, -666);
return dp(coins, amount); }
int dp(int[] coins, int amount) { if (amount == 0) return 0; if (amount < 0) return -1; // 查备忘录,防止重复计算 if (memo[amount] != -666) return memo[amount];
int res = Integer.MAX_VALUE; for (int coin : coins) { // 计算子问题的结果 int subProblem = dp(coins, amount - coin); // 子问题无解则跳过 if (subProblem == -1) continue; // 在子问题中选择最优解,然后加一 res = Math.min(res, subProblem + 1); } // 把计算结果存入备忘录 memo[amount] = (res == Integer.MAX_VALUE) ? -1 : res; return memo[amount]; }}