用滚动数组来减小空间复杂度在求解最长公共子序列问题上用来输出子序列,为什么用二维,不能用一维,在回溯输出时,为什么可以
时间: 2024-02-15 10:01:19 浏览: 58
在求解最长公共子序列问题时,我们通常使用动态规划算法来解决,其中用到了一个二维的状态数组,例如 `dp[i][j]` 表示字符串 `A` 中前 `i` 个字符和字符串 `B` 中前 `j` 个字符的最长公共子序列长度。
当我们需要在输出最长公共子序列时,可以通过回溯从 `dp[m][n]` 开始,根据状态转移方程逐步向左上方移动,将对应的字符添加到结果字符串中,直到 `i=0` 或 `j=0`,即回溯结束。
而在使用滚动数组来减小空间复杂度时,我们只需保留两个一维的数组,例如 `dp[i]` 和 `dp[i-1]`,其中 `dp[i]` 表示字符串 `A` 中前 `i` 个字符和字符串 `B` 中前 `j` 个字符的最长公共子序列长度。在状态转移时,我们只需使用这两个数组即可,具体实现方式可以参考代码:
```python
m, n = len(text1), len(text2)
dp = [0] * (n+1)
for i in range(1, m+1):
pre = 0 # 存储 dp[i-1][j-1] 的值,即左上角的值
for j in range(1, n+1):
tmp = dp[j]
if text1[i-1] == text2[j-1]:
dp[j] = pre + 1
else:
dp[j] = max(dp[j], dp[j-1])
pre = tmp
```
在回溯输出时,我们仍然可以按照上述方式进行,只需保留一个额外的一维数组 `cur`,用于存储当前状态的最长公共子序列长度,即可完成输出最长公共子序列的过程。因为在滚动数组的实现中,我们每次只保留了上一行的状态和当前行的状态,因此在回溯时仍然可以根据上一行的状态和当前行的状态推导出左上角的状态,从而依次输出最长公共子序列中的字符。
阅读全文