> 文档中心 > 「力扣算法合集」

「力扣算法合集」


暴力递归到记忆化搜索到动态规划(双语言(c++和java))

本文是第一章,首先以一个简单题开始

一、爬楼梯

题目介绍:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1:输入:n = 2输出:2解释:有两种方法可以爬到楼顶。1. 1 阶 + 1 阶2. 2 阶示例 2:输入:n = 3输出:3解释:有三种方法可以爬到楼顶。4. 1 阶 + 1 阶 + 1 阶5. 1 阶 + 2 阶6. 2 阶 + 1 阶提示:1 <= n <= 45

二、三个代码如下:

1.暴力递归

c++版本public:    int climbStairs(int n) { return process(n);    }    int process(int n)    { if(n == 1) {     return 1; } if(n == 2) {     return 2; } return process(n - 1) + process(n - 2);    }
java版本public int climbStairs(int n) { return process(n);    }    public int process(int n)    { if(n == 1) {     return 1; } if(n == 2) {     return 2; } return process(n -1) + process(n - 2);    }

2.记忆化搜索

在这里插入图片描述

c++版本public:    int climbStairs(int n) { int dp[101]; for(int i = 0; i < 101; i++) {     dp[i] = -1; } return process(n, dp);    }    int process(int n, int dp[])    { if(n == 1) {     dp[n] = 1;     return 1; } if(n == 2) {     dp[n] = 2;     return 2; } if(dp[n] != -1) {     return dp[n]; } int ans = process(n - 1, dp) + process(n -2,dp); dp[n] = ans; return dp[n];    }

在这里插入图片描述

java版本public int climbStairs(int n) { int[] dp = new int[n + 1]; for(int i = 0; i <= n; i ++) {     dp[i] = -1; } process1(n, dp); return dp[n];    }    int process1(int n, int[] dp)    { if(n == 1) {     dp[n] = 1;     return 1; } if(n == 2) {     dp[n] = 2;     return 2; } if(dp[n] != -1) {     return dp[n]; } int ans = process1(n - 1, dp) + process1(n -2,dp); dp[n] = ans; return dp[n];    }

2.动态规划

在这里插入图片描述

c++版本public:    int climbStairs(int n) { int dp[101]; dp[0] = 1; dp[1] = 1; for(int i = 2; i < 46; i++) {     dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n];    }

在这里插入图片描述

java版本 public int climbStairs(int n) {int[] dp = new int[101]; dp[0] = 1; dp[1] = 1; for(int i = 2; i < 46; i++) {     dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n];    }

总结:

在第一种方法,也就是暴力递归方法中,是我们最容易想到的方法。虽然暴力递归的时间复杂度高,但是它是解决动态规划问题的基础,大家做动态递归一定要会暴力解法。
在第二种方法中,也就是记忆化搜索方法中,我们在暴力递归的方法中增加了一张一维状态表(也叫dp表),可以发现,我们在暴力递归中,之所以运行时间慢,是因为我们对之前的答案没有进行复用,导致我们每次算一个n,还得重新重头开始算。
在第三种方法中,也就是动态规划,我们可以由记忆化搜索方法中的状态表推导出公式f(n) = f(n - 1) + f(n - 2);所以动态规划方法迎刃而解。