前言
通过爬楼梯的不断优化解,来了解算法从基础到数学高度。
一、爬楼梯
二、动态规划
package com.xhu.offer.everyday;
//爬楼梯
public class ClimbStairs {
/*
target:求爬到第n阶楼梯的方法数。
如何才能爬到第n阶楼梯?从n-1阶走一步;从n-2阶走两步;
那么爬到n阶楼梯的方法数 = 爬到n-1阶楼梯的方法数 + 爬到n-2阶楼梯的方法数。
M1:数组记录前面的方法数 + 循环计算。
*/
public int climbStairs(int n) {
int[] dp = new int[n + 1];
dp[0] = dp[1] = 1;
for (int i = 2; i <= n; i++) dp[i] = dp[i - 1] + dp[i - 2];
return dp[n];//返回第到达第n个台阶的方法数。
}
/*
M1-defect:每次计算当前方法数,仅仅与前面两个连续的方法数有关,而方法一采用了数组存了很多随循环失去意义的数。
M2:抓住循环中关键的两个数--即前两个数。所以采用两个变量存储这两个关键方法数即可。
*/
public int climbStairs2(int n) {
int[] dp = new int[]{1,1};
for (int i = 0; i <= n - 2; i++) dp[i & 1] = dp[0] + dp[1];
return dp[n - 2 & 1];
}
//M0-递归模拟,直到走到最后一个台阶,就cnt++。当然时间复杂度很高。
//M3-快速幂,因为这是一个斐波拉契数列,求F(n),有很明显的递归公式。
/*
[1,1] [f(1)] = [f(2)]
[1,0] [f(0)] = [f(1)]
注:快速幂,
1-可递归+判断n是否为奇数偶数来多乘[1,1][1,0],当n=0时返回单位矩阵。
2-可将n拆解为二进制,利用二进制之间的倍数关系 + 幂运算的特点:幂乘为指数相加。
*/
//M4-特征方程+初始条件 得到通项公式。
}
总结
1)递归模拟|动态规划|数组压缩|快速幂递归与迭代|特征方程与通项公式。