题目:
斐波那契数列
解题思路:
动态规划最简单的题目,而且直接给出了数学公式,dp[i]=dp[i-1]+dp[i-2]。
注意是答案需要去模
代码:
- 递归
错误示范——超时
int fib(int n) {
if(n==0)
return 0;
else if(n==1)
return 1;
return (fib(n-1)+fib(n-2))%1000000007;
为何会超时呢?
因为中间存在很多次计算,比如fib(3),他需要fib(2)和fib(1),fib(4)需要fib(3)和fib(2),因而在计算过程中,每一次fib(2),fib(3)都需要重复不断的计算,浪费了大量的时间。
所以我们需要减少这样的重复计算,因而利用一个哈希表,把计算过的fib(n)的值存在哈希表中,这样就可以减少大量运算。
private HashMap<Integer,Integer> map;
public int fib(int n){
map = new HashMap(n);
return dfs(n);
}
public int dfs(int n){
if(n == 0){
return 0;
}else if(n == 1){
return 1;
}else if(map.containsKey(n)){
return map.get(n);
}
//哈希表中没有,先算出来,然后再放到哈希表中,为下次使用。
int a = dfs(n - 1) % 1000000007;
int b = dfs(n - 2) % 1000000007;
map.put(n-1,a);
map.put(n-2,b);
map.put(n,(a+b)%1000000007);
return map.get(n);
}
- 迭代
1.当i=0的时候,dp[i]=0;当i=1时,dp[i]=1,确定初始条件
2.根据方程迭代dp[i]=dp[i-1]+dp[i-2]
public int fib(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
int[] array = new int[n+1];
array[0] = 0;
array[1] = 1;
for(int i = 2; i <= n; i++){
array[i] = (array[i-1] + array[i-2]) % 1000000007;
}
return array[n];
}
ps:这里注意创建数组大小为:n+1。
总结:迭代的方法更加简单,递归方法如果没有哈希表肯定会超过时间,那大家有没想过为什么迭代和递归的区别在哪里,我想了想,不知道对不对,递归是从n一直到基础条件,而迭代则是从基础条件出发推导到n,可以说递归是逆向过程,而迭代是正向过程,所以我觉得可以用迭代的方法,往往也可以用递归,后面的动态规划基本都用是迭代的方法,当然是用递归也是可以。