📌  相关文章
📜  具有相邻字符的最长子序列(1)

📅  最后修改于: 2023-12-03 14:50:07.829000             🧑  作者: Mango

具有相邻字符的最长子序列

介绍

在一个字符串中,如果某个字符与它右边或下边的字符相同,则这两个字符是相邻的。例如在字符串 "abcbc" 中,'b' 和 'c' 是相邻的。一个子序列是指从原始字符串中找出一些字符,这些字符在原始字符串中的相对位置不变,并按照先后顺序排列。现在需要你求出一个字符串中具有相邻字符的最长子序列。例如在字符串 "abcbc" 中,"bcbc" 就是该字符串中具有相邻字符的最长子序列。

问题解决方案
动态规划

假设 $dp[i][j]$ 表示以 $i, j$ 为结尾的具有相邻字符的最长子序列的长度,那么对于每一对相邻字符,如果它们相等,那么有:

$$dp[i][j] = max(dp[k][l]) + 1$$

其中 $(k,l)$ 是 $(i-1,j), (i,j-1), (i-1,j-1)$ 中的一个。

时间复杂度为 $O(n^2)$。

def longestSubsequence(s: str) -> int:
    n = len(s)
    dp = [[0] * (n + 1) for _ in range(n + 1)]
    ans = 0
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            if s[i - 1] == s[j - 1] and i != j:
                dp[i][j] = max(dp[k][l] for k in range(i - 1) for l in range(j - 1) if k < i and l < j) + 1
                ans = max(ans, dp[i][j])
    return ans
哈希表

对于字符串的所有子串,我们可以通过哈希表来进行预处理,记录该子串是否具有相邻字符,并记录其最长长度。

时间复杂度为 $O(n^3)$。

def longestSubsequence(s: str) -> int:
    n = len(s)
    ans = 0
    for i in range(n):
        for j in range(i + 1, n):
            sub = s[i:j + 1]
            if all(sub[k] != sub[k + 1] for k in range(len(sub) - 1)):
                ans = max(ans, len(sub))
    return ans
总结

本题可以采用动态规划或哈希表两种解法。动态规划时间复杂度为 $O(n^2)$,哈希表时间复杂度为 $O(n^3)$。在实际应用中,动态规划的解法更加常见和高效。

参考文献:

  • LeetCode 官方题解. https://leetcode-cn.com/problems/longest-subsequence/