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

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

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

递归的基本概念

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

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

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)

相关推荐
curemoon18 分钟前
理解都远正态分布中指数项的精度矩阵(协方差逆矩阵)
人工智能·算法·矩阵
柃歌26 分钟前
【UCB CS 61B SP24】Lecture 7 - Lists 4: Arrays and Lists学习笔记
java·数据结构·笔记·学习·算法
柃歌36 分钟前
【UCB CS 61B SP24】Lecture 4 - Lists 2: SLLists学习笔记
java·数据结构·笔记·学习·算法
SKYDROID云卓小助手2 小时前
无人设备遥控器之如何分享数传篇
网络·人工智能·算法·计算机视觉·电脑
Lqingyyyy2 小时前
P2865 [USACO06NOV] Roadblocks G 与最短路的路径可重复的严格次短路
开发语言·c++·算法
WHATEVER_LEO2 小时前
【每日论文】Text-guided Sparse Voxel Pruning for Efficient 3D Visual Grounding
人工智能·深度学习·神经网络·算法·机器学习·自然语言处理
Vacant Seat3 小时前
贪心算法-买卖股票的最佳时机
java·数据结构·算法·贪心算法
郑州吴彦祖7723 小时前
数据结构——二叉树经典习题讲解
java·数据结构·算法·leetcode
lyx1426063 小时前
leetcode 8. 字符串转换整数 (atoi)
算法
qy发大财4 小时前
跳跃游戏II(力扣45)
算法·leetcode