算法:三步问题

描述:

  三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。

个人思路:

  暴力破解,多层循环,每步阶梯相加值等于最终值时上楼方式+1

大神思路:

  三步问题前三级楼梯,上楼方式固定为1,2,4种,从第四步开始,可用方程式代替,每增加一级楼梯,结果 = 前三级之和。

  

// n为楼梯数
public int upstair(int n) {
    int[] result = new int[n +1];  // 要初始化数组从1开始算
    if (n > 1) result[1] = 1;  
    if (n > 2) result[2] = 2;
    if (n > 3) result[3] = 4;  // 前三步上楼方式时特殊情况固定的,若不加判断,n< 3则会数组越界
    
// 从4开始,是因为4以后才能用到以下循环计算上楼方式 每增加一级,为[n - 1] + [n - 2] + [n - 3]之和。 for(int i = 4; i <= n; ++i) { result[i] = ((result[i - 3] + result[i - 2])%1000000007 + result[i - 1])%1000000007 // 2次模1000000007 防止int溢出
  } 
  return result[i];
}

 

动态规划

1、创建初始条件

2、创建基础方程式,基础方程式创建较难,要知道问题的临界点,创建可复用方程。

3、缓存并复用第二步结果

4、从小到大执行,类似递归,但递归容易内存溢出,并且执行时间为log(2^n)。而缓存并复用,则把执行时间降低为log(n)。用空间换时间。

posted @ 2021-04-03 11:34  带着梦想的咸鱼  阅读(193)  评论(0编辑  收藏  举报