算法题——动态规划
509.斐波那契数列
递归的思路很简单,首先定义一个方法func,每次里面递归调用func(x-1),func(x-2),递归出口是func(0)=0,func(1)=1
class Solution {public int fib(int n) {if(n==0) return 0;if(n==1) return 1;return fib(n-1)+fib(n-2);}
}
但是递归的性能很差,因为需要层层调用,考虑用空间换时间,用一个一维数组记录每一个函数计算的中间值,这样就避免了重复计算
动态规划五步:
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
class Solution {public int fib(int n) {if(n<=1) return n;int[] dp = new int[n+1]; //dp[i]表示第i个数的斐波那契数dp[0] = 0;dp[1] = 1; //dp数组初始值for(int i=2;i<n+1;i++){dp[i] = dp[i-1] + dp[i-2]; //状态转移方程}return dp[n];}
}
70.爬楼梯
class Solution {public int climbStairs(int n) {if(n<=2) return n;int[] dp = new int[n+1];dp[1] = 1;dp[2] = 2;for(int i=3;i<n+1;i++){dp[i] = dp[i-1] + dp[i-2];}return dp[n];}
}
62.不同路径
class Solution {public int uniquePaths(int m, int n) {int[][] dp = new int[m+1][n+1];for(int j=1;j<=n;j++){dp[1][j] = 1;}for(int i=2;i<=m;i++){dp[i][1] = 1;}for(int i=2;i<=m;i++){for(int j=2;j<=n;j++){dp[i][j] = dp[i-1][j] + dp[i][j-1];}}return dp[m][n];}
}