leetcode. (1141)Longest Common Subsequence. (1092)Shortest Common Supersequence.

4 篇文章 0 订阅
2 篇文章 0 订阅

求多个子串 { s 1 , . . . , s n } \{s_1,...,s_n\} {s1,...,sn}的序列组合问题.

核心点要关注多维DP数组所存储的信息, DP数组里的信息有:

  1. 字符串 s i s_i si s j s_j sj相互比较的信息
    • 是一个隐马尔科夫的过程dp[i][j]的状态只与他的pre状态有关.
    • 其pre状态是根据状态转移方程来定的.
  2. 回溯时要从后往前回溯, 根据状态的变化规则和想要的最终字符串回溯即可.

对于高纬度多个字符串相比较, 其也是一样的, 只不过状态转移方程的参数要变多.

下面是LCS和SCS的代码和回溯过程.

# %%

class Solution:
    def shortestCommonSupersequence(self, str1: str, str2: str) -> str:
        """Find the Shortest Super Sequence which contains srt1 and str2.  
            Input:  
                str1: an English word string.  
                str2: an English word string.
            Output:
                1. An English word string.
            Perfomance:
                O(n^2)
                O(n^2)
            Tips: 
                It's similar to the Longest Common Subsequence.  
                We just take a special strategy to regenerate string when it's different.
        """
        # Checks
        max_size_str = 10**5
        if str1 is None or str2 is None:
            raise Exception("The parameter is None.")
        if str1 == "" or str2 == "":
            return str2+str1
        if len(str1) > max_size_str or len(str2) > max_size_str:
            raise Exception(
                "The parameter is too long, please chang ohter algorithms.")
        a, b = len(str1), len(str2)
        # Dynamic Array.
        dp = [[0 for _ in range(b+1)] for _ in range(a+1)]
        for i in range(a):
            for j in range(b):
                if str1[i] == str2[j]:
                    # State Transition Equation. 1
                    dp[i+1][j+1] = dp[i][j] + 1
                else:
                	# State Transition Equation. 2
                    dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
        # Regenerate SuperSequence.
        scs = []
        # Regenerate Subsequence.
        lcs = []
        while a > 0 and b > 0:
            # Common character
            if str1[a-1] == str2[b-1]:
                scs.append(str1[a-1])
                lcs.append(str1[a-1])
                a -= 1
                b -= 1
            elif dp[a][b] == dp[a-1][b]:
                scs.append(str1[a-1])
                a -= 1
            elif dp[a][b] == dp[a][b-1]:
                scs.append(str2[b-1])
                b -= 1
        scs = "".join(scs[::-1])
        # Recurse str1 or str2.
        # Then add the rest of characters.
        if a:
            scs = str1[:a]+scs
        if b:
            scs = str2[:b]+scs
        print("".join(lcs[::-1]))
        return scs


if __name__ == "__main__":
    s1, s2 = "bcacaaab", "bbabaccc"
    print(Solution().shortestCommonSupersequence(s1, s2))

# %%

结果

LCS: bcc
SCS: bbabaccacaaab

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值