📜  门| GATE-IT-2004 |问题4(1)

📅  最后修改于: 2023-12-03 15:42:19.561000             🧑  作者: Mango

门 GATE-IT-2004 问题4

GATE-IT-2004 是印度的一个计算机科学入门考试,问题4主要涉及字符串操作和算法设计。以下是该问题的介绍、分析和解决方案。

问题描述

给定两个字符串 $s_1$ 和 $s_2$,请编写一个函数 longest_common_subsequence(),计算并返回它们的最长公共子序列的长度。注意,子序列不要求在原字符串中是连续的。

例如:

s1 = 'ABCDGH'
s2 = 'AEDFHR'
longest_common_subsequence(s1, s2) -> 3(最长公共子序列是 'ADH')
问题分析

这是一个存在多种算法解法的普遍问题,其中比较直观的一种是 动态规划(Dynamic Programming)。假设 $dp[i][j]$ 表示 $s_1[0, i)$ 和 $s_2[0, j)$ 的最长公共子序列长度,则我们可以这样递推求解 $dp[i][j]$:

  • 若 $s_1[i-1] == s_2[j-1]$,则 $dp[i][j] = dp[i-1][j-1] + 1$;
  • 否则,$dp[i][j] = max(dp[i-1][j], dp[i][j-1])$。

因此,dp[i][j] 的值只与 $dp[i-1][j-1], dp[i-1][j], dp[i][j-1]$ 有关,可以使用滚动数组(Rolling array)将空间复杂度降到 O(min(m,n)),其中 m 和 n 分别是字符串 $s_1$ 和 $s_2$ 的长度。

解决方案

根据上述分析,下面是 Python 3 中的动态规划实现,返回公共子序列长度。

def longest_common_subsequence(s1: str, s2: str) -> int:
    m, n = len(s1), len(s2)
    dp = [[0] * (n+1) for _ in range(2)]
    for i in range(1, m+1):
        for j in range(1, n+1):
            if s1[i-1] == s2[j-1]:
                dp[i%2][j] = dp[(i-1)%2][j-1] + 1
            else:
                dp[i%2][j] = max(dp[(i-1)%2][j], dp[i%2][j-1])
    return dp[m%2][n]
总结

本文介绍了 GATE-IT-2004 问题4,涉及字符串操作和动态规划算法。根据这些基础可以进一步理解和运用更复杂的算法,例如基于 LCS(Longest Common Subsequence)的字符串比较和相似度计算等。