公共子序列连续与不连续

参考例题 力扣718 https://leetcode.cn/problems/maximum-length-of-repeated-subarray/solutions/310917/yi-zhang-biao-ba-ju-hua-kan-dong-dong-tai-gui-hua-/
力扣 1143 https://leetcode.cn/problems/longest-common-subsequence/solutions/696989/fu-xue-ming-zhu-er-wei-dong-tai-gui-hua-r5ez6/

1. 最长公共子序列问题

状态转移方程:
如果 text1[i-1] == text2[j-1],说明当前字符相同,可以将最长公共子序列长度加一,即 dp[i][j] = dp[i-1][j-1] + 1。
如果 text1[i-1] != text2[j-1],说明当前字符不同,需要在 text1 或 text2 中选择一个字符舍弃,取两者的最大值,即 dp[i][j] = max(dp[i-1][j], dp[i][j-1])。

def longest_common_subsequence(text1, text2):
    m, n = len(text1), len(text2)
    # 创建一个二维数组用于存储最长公共子序列的长度
    dp = [[0] * (n + 1) for _ in range(m + 1)]

    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if text1[i - 1] == text2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

    return dp[m][n]

在这个问题中,动态规划数组dp[i][j]表示text1的前i个字符与text2的前j个字符的最长公共子序列的长度。通过填充这个二维数组,我们可以得到最终的结果。

2. 两个数组的最长公共子数组问题

状态转移方程:
如果 nums1[i-1] == nums2[j-1],说明当前元素相同,可以将最长公共子数组长度加一,即 dp[i][j] = dp[i-1][j-1] + 1。
同时,每次计算新的 dp[i][j] 时,需要比较并更新 max_length,以保持最长公共子数组的长度。

def find_length(nums1, nums2):
    m, n = len(nums1), len(nums2)
    # 创建一个二维数组用于存储最长公共子数组的长度
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    max_length = 0

    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if nums1[i - 1] == nums2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1
                max_length = max(max_length, dp[i][j])

    return max_length

在这个问题中,动态规划数组dp[i][j]表示以nums1的第i个元素结尾和nums2的第j个元素结尾的最长公共子数组的长度。通过填充这个二维数组,我们可以找到最长的公共子数组的长度。

总体来说,两个问题的动态规划思路都是基于填充一个二维数组,但是具体的状态转移方程和数组的含义在不同问题中有所不同。

posted @ 2024-02-19 10:55  taixian  阅读(43)  评论(0)    收藏  举报