上台阶
有一楼梯共n级,刚开始时你在第一级,若每次只能跨上一级或者二级,要走上n级,共有多少走法?注:规定从一级到一级有0种走法。给定一个正整数int n,请返回一个数,代表上楼的方式数。保证n小于等于100。为了防止溢出,请返回结果Mod 1000000007的值。
方法一:递归分治
递归分治就是把一个大的问题切分成k个小的子问题,子问题相较于原问题独立又有联系,然后递归地解决这些子问题,再把这些子问题合并得到原问题的答案。
思路:可以走一步,也可以走两步,从第n-1阶再走一步能到第n阶,从第n-2阶一次走两步能到第n阶。 所以,f(n)=f(n-1)+f(n-2)
public class GoUpstairs {
//递归
public static int countWays(int n)
{
if(n == 1)
return 0;
if(n == 2)
return 1;
if(n == 3)
return 2;
if(n > 3)
return countWays(n-1) + countWays(n-2);
return 0;
}
方法二:动态规划
动态规划是把待求解问题分解成一个个子问题,原问题由交叠的子问题所构成,即他们存在递推关系,求出较小的子问题从而逐步递推出原问题的答案。
思路:f(1)=0,f(2)=1,f(3)=2,
已知存在这样的关系:f(n)=f(n-1)+f(n-2),用数组保存每一步的解
public static int countWays(int n) {
//动态规划
if(n==1){
return 0;
}else if(n==2){
return 1;
}else if(n==3){
return 2;
}else{
long[] row = new long[n];
row[0]=0;
row[1]=1;
row[2]=2;
for(int i=3;i<n;i++){
row[i]=row[i-1]%1000000007+row[i-2]%1000000007;
}
return ((int)row[n-1]%1000000007);
}
}