1、斐波那契:f(n)=f(n-1)+f(n-2)
//暴力递归 自顶向下
//对已经计算的值没有记忆,每一次传递都要现算
//n^2
var FBNQ=function(n){
if(n==0){
return 0;
}
if(n==1){
return 1;
}
if(n==2){
return 1;
}
return FBNQ(n-1)+FBNQ(n-2);
}
//有记忆的递归
//自顶向下
//n^2
var MFBNQ=function(n){
var arr=[];
var handle=function(){
if(arr[n]){//arr[n]有值则返回arr[n]
//记忆化
return arr[n];
}
if(n==0)
{
return 0;
}
if(n==1)
{
return 1;
}
if(n==2){
return 1;
}
arr[n]=handle(n-1)+handle(n-2);
return arr[n];
}
return handle(n);
}
//上面还很麻烦
//动态规划 穷举 重叠子问题--最优子结构--状态转移方程
//自底向上的
//时间复杂n
//空间复杂n
var DTFBNQ=function(n){
//根据重叠子问题定义状态
//寻找状态转移方程
//确定状态 dp 见到dp就是动态规划
//确定输出值
var dp=[0,1,1];
for(var i=3;i<=n;i++)
{
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
//优化
// 就是用变量存每个值,然就进行操作
//空间复杂度可以降到1
//例子:70
2、跳台阶:f(n)=f(n-1)+f(n-2)
网址:70. 爬楼梯 - 力扣(Leetcode)https://leetcode.cn/problems/climbing-stairs/n=1 1 1种
n=2 1 1、2 2种
n=3 1 1 1、1 2、2 1 3种
n=4 1 1 1 1、1 1 2、1 2 1 、2 1 1、2 2 5种
n=5 1 1 1 1 1、1 1 1 2、1 1 2 1、1 2 1 1、1 2 2、2 1 1 1、2 2 1、2 1 2 8种
f(n)=f(n-1)+f(n-2)
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
if(n==1)
{
return 1;
}
if(n==2)
{
return 2;
}
if(n==3){
return 3;
}
var pre=1;
var after=2;
var result=3;
for(var a=4;a<=n;a++){
pre=after;
after=result;
result=pre+after;
}
return result;
};
console.log(climbStairs(5));
3、路径
网址:62. 不同路径 - 力扣(Leetcode)https://leetcode.cn/problems/unique-paths/
一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
/**
* @param {number} m
* @param {number} n
* @return {number}
*/
var uniquePaths = function(m, n) {
var arr_arr=new Array(m).fill(0).map(()=>new Array(n).fill(0));
//创建二维数组,并在数组的每个位置上赋值成0
for(let i=0;i<m;i++){
arr_arr[i][0]=1;
}
for(let j=0;j<n;j++){
arr_arr[0][j]=1;
}
for(let i=1;i<m;i++)
{
for(let j=1;j<n;j++)
{
arr_arr[i][j]=arr_arr[i-1][j]+arr_arr[i][j-1];
}
}
return arr_arr[m-1][n-1];
//因为数组是从0开始计数的,所以最后得到的结果是要在原来的基础上减一
};
var m=3,n=2;
//0 1
//1 2
//1 3
console.log(uniquePaths(m,n));
输出结果:
4、路径2
网址:63. 不同路径 II - 力扣(Leetcode)https://leetcode.cn/problems/unique-paths-ii/description/一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1
和 0
来表示。
/**
* @param {number[][]} obstacleGrid
* @return {number}
*/
var uniquePathsWithObstacles = function (obstacleGrid) {
var row = obstacleGrid.length;
// console.log(row);
var column = obstacleGrid[0].length;
var path = new Array(row).fill(0).map(() => new Array(column).fill(0));
// console.log(path);
//初始化数组,每个位置上全为0
//根据给定的数组去变换第一行第一列
//一旦有障碍物,则第一行第一列在这这个障碍物之后的位置上的数字均是0
path[0][0]=1;
for(let i=0;i<row;i++)
{
path[i][0]=1;
if(obstacleGrid[i][0]==1)
{
while(i<row)
{
path[i][0]=0;
i++;
}
}
}
for(let i=0;i<column;i++)
{ path[0][i]=1;
if(obstacleGrid[0][i]==1)
{
while(i<column)
{
path[0][i]=0;
i++;
}
}
}
// console.log(path);
for (i = 1; i < row; i++) {
for (j = 1; j < column; j++) {
if (obstacleGrid[i][j] == 1) {
continue;
}
else {
path[i][j] = path[i - 1][j] + path[i][j - 1];
}
// console.log(path);
}
}
//console.log(path);
return path[row - 1][column - 1];
};
// var obstacleGrid = [[0, 0, 0], [0, 1, 0], [0, 0, 0]]
// var obstacleGrid = [[1,0]]
var obstacleGrid=[[0,0],[1,1],[0,0]]
console.log(uniquePathsWithObstacles(obstacleGrid));
输出截图:
这个想法挺简单,实现起来也没什么难度,但是时间、空间复杂度都有点高,可以再适当优化。