数据结构与算法之 leetcode 动态规划状态定义 一维 / 二维状态设计

数据结构与算法阿木 发布于 2025-07-12 15 次阅读


摘要:

动态规划(Dynamic Programming,简称DP)是一种解决优化问题的算法思想,它通过将复杂问题分解为子问题,并存储子问题的解以避免重复计算,从而提高算法效率。在LeetCode等编程竞赛平台中,动态规划是解决算法题目的重要工具。本文将围绕动态规划状态定义这一主题,探讨一维和二维状态设计在LeetCode中的应用,并通过实例代码进行分析。

一、

动态规划的核心在于状态定义,即如何将问题分解为子问题,并定义每个子问题的状态。状态定义的优劣直接影响到动态规划算法的复杂度和可读性。本文将首先介绍一维和二维状态设计的基本概念,然后通过LeetCode上的实例题目进行分析。

二、一维状态设计

一维状态设计是指将问题分解为一系列子问题,每个子问题只与一个变量相关。这种设计方式适用于子问题之间没有重叠的情况。

1. 状态定义

一维状态通常用一个一维数组表示,数组的每个元素代表一个子问题的解。例如,对于斐波那契数列问题,我们可以定义状态`dp[i]`表示斐波那契数列的第`i`项。

2. 状态转移方程

状态转移方程描述了子问题之间的关系,即如何根据子问题的解推导出父问题的解。以斐波那契数列为例,状态转移方程为`dp[i] = dp[i-1] + dp[i-2]`。

3. 初始化

初始化状态数组,通常需要根据问题的具体要求进行。以斐波那契数列为例,初始化`dp[0] = 0`,`dp[1] = 1`。

4. 实例代码

python

def fib(n):


if n <= 1:


return n


dp = [0] (n + 1)


dp[0], dp[1] = 0, 1


for i in range(2, n + 1):


dp[i] = dp[i - 1] + dp[i - 2]


return dp[n]


三、二维状态设计

二维状态设计是指将问题分解为一系列子问题,每个子问题与两个变量相关。这种设计方式适用于子问题之间存在重叠的情况。

1. 状态定义

二维状态通常用一个二维数组表示,数组的每个元素代表一个子问题的解。例如,对于矩阵乘法问题,我们可以定义状态`dp[i][j]`表示矩阵`A`的第`i`行与矩阵`B`的第`j`列的乘积。

2. 状态转移方程

状态转移方程描述了子问题之间的关系,即如何根据子问题的解推导出父问题的解。以矩阵乘法为例,状态转移方程为`dp[i][j] = max(dp[i][k] dp[k][j] for k in range(m))`。

3. 初始化

初始化状态数组,通常需要根据问题的具体要求进行。以矩阵乘法为例,初始化`dp[i][j] = 0`。

4. 实例代码

python

def matrix_multiply(A, B):


m, n, p = len(A), len(B[0]), len(B)


dp = [[0] p for _ in range(m)]


for i in range(m):


for j in range(p):


for k in range(n):


dp[i][j] = max(dp[i][j], A[i][k] B[k][j])


return dp


四、LeetCode实例分析

1. 题目描述:给定一个整数数组,找到连续子数组的最大和。

2. 一维状态设计

python

def max_subarray_sum(nums):


max_sum = current_sum = nums[0]


for num in nums[1:]:


current_sum = max(num, current_sum + num)


max_sum = max(max_sum, current_sum)


return max_sum


3. 二维状态设计

python

def max_subarray_sum(nums):


n = len(nums)


dp = [[0] n for _ in range(n)]


for i in range(n):


dp[i][i] = nums[i]


for length in range(2, n + 1):


for i in range(n - length + 1):


j = i + length - 1


dp[i][j] = max(nums[i], nums[j], dp[i + 1][j - 1] + nums[i:j + 1])


return max(dp[i][j] for i in range(n) for j in range(n))


五、总结

本文介绍了动态规划状态定义的基本概念,并通过一维和二维状态设计在LeetCode实例中的应用进行了分析。一维状态设计适用于子问题之间没有重叠的情况,而二维状态设计适用于子问题之间存在重叠的情况。在实际应用中,我们需要根据问题的具体要求选择合适的状态设计方法,以提高算法的效率。

参考文献:

[1] 动态规划之美,陈旸,电子工业出版社,2017年。

[2] LeetCode官网,https://leetcode.com/。