leetcode_1143_最长公共子序列

1、题目描述:

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。

一个字符串的 子序列
是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。 两个字符串的 公共子序列
是这两个字符串所共同拥有的子序列。
示例1:
输入:text1 = “abcde”, text2 = “ace”
输出:3
解释:最长公共子序列是 “ace” ,它的长度为 3 。
示例2:
输入:text1 = “abc”, text2 = “abc”
输出:3
解释:最长公共子序列是 “abc” ,它的长度为 3 。
示例3:
输入:text1 = “abc”, text2 = “def”
输出:0
解释:两个字符串没有公共子序列,返回 0 。

解法一:
动态数组:
定义二维数组dp[i][j],dp[i][j]表示text1前[i]个数与text2的前[j]个数的最长公共子序列的长度
dp[i][0]与dp[0][j]的初始值均为0
如果text1[i - 1] == text2[j - 1],则dp[i][j] = dp[i - 1][j - 1] + 1
如果text1[i - 1] != text2[j - 1],则dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
空间复杂度 O(n * m), n,m为字符串的长度

def longestCommonSubsequence( text1: str, text2: str) :
    text1_ls = list(text1) #将字符串转成list
    text2_ls = list(text2)
    if len(text1_ls) == 0 or text1_ls == None:
        return 0
    if len(text2_ls) == 0 or text2_ls == None:
        return 0
    #定义一个列数为text1_ls + 1,行数text2_ls + 1的二维数组
    dp = [[0] * (len(text1_ls) + 1) for _ in range(len(text2_ls) + 1)]
   # 遍历行数,
    for i in range(1, len(text2_ls) + 1):
        for j in range(1, len(text1_ls) + 1):
            if text2_ls[i - 1] == text1_ls[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[len(text2_ls)][len(text1_ls)]

优化1:将dp定义为2行的二维数组,减小空间复杂度

def longestCommonSubsequence_dp1( text1: str, text2: str) :
    text1_ls = list(text1)
    text2_ls = list(text2)
    if len(text1_ls) == 0 or text1_ls == None:
        return 0
    if len(text2_ls) == 0 or text2_ls == None:
        return 0
    
    dp = [[0] * (len(text1_ls) + 1) for _ in range(2)]
    for i in range(1, len(text2_ls) + 1):
        for j in range(1, len(text1_ls) + 1):
            row = i % 2
            prerow = (i - 1) % 2
            if text2_ls[i - 1] == text1_ls[j - 1]:
                dp[row][j] = dp[prerow][j - 1] + 1
            else:
                dp[row][j] = max(dp[prerow][j], dp[i % 2][j - 1 ])
    return dp[len(text2_ls) % 2][len(text1_ls)] 

优化2,将二维数组优化成一维数组,进一步降低空间复杂度

def longestCommonSubsequence_dp2( text1: str, text2: str) :
    text1_ls = list(text1)
    text2_ls = list(text2)
    if len(text1_ls) == 0 or text1_ls == None:
        return 0
    if len(text2_ls) == 0 or text2_ls == None:
        return 0
    
    dp = [0] * (len(text1_ls) + 1)
    for i in range(1, len(text2_ls) + 1):
        cur = 0
        for j in range(1, len(text1_ls) + 1):
            leftTop = cur
            cur = dp[j]

            if text2_ls[i - 1] == text1_ls[j - 1]:
                dp[j] = leftTop + 1
            else:
                dp[j] = max(dp[j], dp[j - 1 ])
    return dp[len(text1_ls)] 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值