从递归到动态规划(一维)

从递归到一维动态规划的理解

动态规划是一种通过把原问题分解为相对简单的子问题,并保存子问题的解来避免重复计算,从而解决复杂问题的算法策略。一维动态规划是动态规划中较为基础的一类,它通常只需要一个一维数组来保存子问题的解。我们可以从递归的角度逐步引出一维动态规划。

递归的基本概念

递归是指在函数的定义中使用函数自身的方法。在解决问题时,递归通常将大问题分解为形式相同的小问题,直到达到最小的、可以直接求解的子问题(即递归的终止条件)。不过,递归可能会存在大量的重复计算,导致时间复杂度很高。

以斐波那契数列为例理解从递归到一维动态规划的转变步骤

1. 递归实现斐波那契数列

斐波那契数列的定义为:(F(n) = F(n - 1)+F(n - 2)),其中 (F(0)=0,(F(1)=1。

java 复制代码
public static int fib1(int n) {
		return f1(n);
	}

	public static int f1(int i) {
		if (i == 0) {
			return 0;
		}
		if (i == 1) {
			return 1;
		}
		return f1(i - 1) + f1(i - 2);
	}

递归的问题:在计算 F(n) 时,会多次重复计算 F(n - 1)、F(n - 2) 等子问题。例如,计算 F(5) 时,(F(3) 会被多次计算,这会导致时间复杂度呈指数级增长,为 O(2^n)。

2. 记忆化搜索实现斐波那契数列(自顶向下动态规划)

为了避免递归中的重复计算,我们可以使用一维数组来保存已经计算过的子问题的解,遇到时直接返回。

java 复制代码
public static int fib2(int n) {
		int[] dp = new int[n + 1];
		Arrays.fill(dp, -1);
		return f2(n, dp);
	}

	public static int f2(int i, int[] dp) {
		if (i == 0) {
			return 0;
		}
		if (i == 1) {
			return 1;
		}
		if (dp[i] != -1) {
			return dp[i];
		}
		int ans = f2(i - 1, dp) + f2(i - 2, dp);
		dp[i] = ans;
		return ans;
	}
3. 严格位置依赖实现斐波那契数列(自底向上动态规划)

是利用数列项间严格位置依赖关系,从最小子问题起按序计算,避免递归重复计算以提升效率,让代码更易读且有空间优化潜力。

java 复制代码
public static int fib3(int n) {
		if (n == 0) {
			return 0;
		}
		if (n == 1) {
			return 1;
		}
		int[] dp = new int[n + 1];
		dp[1] = 1;
		for (int i = 2; i <= n; i++) {
			dp[i] = dp[i - 1] + dp[i - 2];
		}
		return dp[n];
	}
4. 用有限几个变量优化空间

为了简化代码。

java 复制代码
public static int fib4(int n) {
		if (n == 0) {
			return 0;
		}
		if (n == 1) {
			return 1;
		}
		int lastLast = 0, last = 1;
		for (int i = 2, cur; i <= n; i++) {
			cur = lastLast + last;
			lastLast = last;
			last = cur;
		}
		return last;
	}

相应题目链接

509. 斐波那契数 - 力扣(LeetCode)

983. 最低票价 - 力扣(LeetCode)

91. 解码方法 - 力扣(LeetCode)

639. 解码方法 II - 力扣(LeetCode)

264. 丑数 II - 力扣(LeetCode)

32. 最长有效括号 - 力扣(LeetCode)

467. 环绕字符串中唯一的子字符串 - 力扣(LeetCode)

940. 不同的子序列 II - 力扣(LeetCode)

相关推荐
网安秘谈4 分钟前
密码学国密算法深度解析:SM2椭圆曲线密码与SM3密码杂凑算法
算法·密码学
小羊在奋斗1 小时前
【算法】动态规划:回文子串问题、两个数组的dp
算法·动态规划
编程在手天下我有2 小时前
机器学习中的 K-均值聚类算法及其优缺点
算法·均值算法
喜欢理工科2 小时前
18 C语言标准头文件
c语言·python·算法·c语言标准头文件
a13096023362 小时前
编译原理 pl0 词法解析器 使用状态机与状态矩阵,和查找上一步得到分析
线性代数·算法·矩阵
爱笑的Sunday2 小时前
【LeetCode 题解】算法:15.三数之和
java·数据结构·算法·leetcode
John Art3 小时前
PAT甲级(Advanced Level) Practice 1028 List Sorting
算法
花鱼白羊3 小时前
代码随想录刷题day52|(二叉树篇)106.从中序与后序遍历序列构造二叉树(▲
算法
ゞ 正在缓冲99%…3 小时前
leetcode3.无重复字符的最长字串
算法·leetcode·滑动窗口
一只_程序媛3 小时前
【leetcode hot 100 739】每日温度
算法·leetcode·职场和发展