代码随想录算法训练营第五十天| LeetCode300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组、1143.最长公共子序列

300.最长递增子序列

题目描述: 300.最长递增子序列.

解法

dp

python 复制代码
class Solution(object):
    def lengthOfLIS(self, nums):
        if len(nums) <= 1:
            return len(nums)
        dp = [1] * len(nums)
        res = 0
        for i in range(1,len(nums)):
            for j in range(i):
                if nums[j] < nums[i]:
                    dp[i] = max(dp[i],dp[j]+1)
            res = max(res,dp[i])
        return res

考虑的是:以当前节点为终点的递增序列,最长为多少。

674. 最长连续递增序列

题目描述: 674. 最长连续递增序列.

解法

dp

python 复制代码
class Solution(object):
    def findLengthOfLCIS(self, nums):
        if len(nums) <= 1:
            return len(nums)
        dp = [1] * len(nums)
        res = 0
        for i in range(1,len(nums)):
            if nums[i-1] < nums[i]:
                dp[i] = dp[i-1] + 1
            res = max(res,dp[i])
        return res

718. 最长重复子数组

题目描述: 718. 最长重复子数组.

解法

二维dp

python 复制代码
class Solution:
    def findLength(self, nums1: List[int], nums2: List[int]) -> int:
        dp = [[0] * (len(nums1)+1) for _ in range(len(nums2)+1)]
        res = 0
        for i in range(1,len(nums2)+1):
            for j in range(1,len(nums1)+1):
                if nums2[i-1] ==  nums1[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                res = max(res,dp[i][j])
        return res

滚动dp

python 复制代码
class Solution(object):
    def findLength(self, nums1, nums2):
        dp = [0]*(len(nums1)+1)
        res = 0
        for i in range(1,len(nums2)+1):
            for j in range(len(nums1),0,-1):
                if nums2[i-1] == nums1[j-1]:
                    dp[j] = dp[j-1] + 1
                else:
                    dp[j] = 0
                res = max(res,dp[j])
        return res

只要dp[i][j]是由dp[i-1][j]或者dp[i-1][j-1]决定的,就可以使用滚动数组

本体的主要思路就是,遍历每个字符串的每一位,然后对比以该位为终点的相同的子串有多少位,如果该位相同,那就在前一位的基础上+1,否则的话,就置为0

1143.最长公共子序列

题目描述: 1143.最长公共子序列.

解法

二维dp

python 复制代码
class Solution(object):
    def longestCommonSubsequence(self, text1, text2):
        dp = [[0] * (len(text2)+1) for _ in range(len(text1)+1)]
        for i in range(1,len(text1)+1):
            for j in range(1,len(text2)+1):
                if text1[i-1] == text2[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                else:
                    dp[i][j] = max(dp[i][j-1],dp[i-1][j])
                res = max(res,dp[i][j])
        return dp[len(text1)][len(text2)]

需要考虑两个字符串任意减少一个的情况

子序列和子数组不同的就在于,子数组一定是连续的,所以考虑dp[i][j]时一定要考虑dp[i-1][j-1]

但是子序列就不一样了,如果dp[i][j]不能由dp[i-1][j-1]得到,那就得考虑每个单词各削减一位的情况了。

同样,因为是子序列,所以不需要考虑最长在哪,返回最后的dp就一定是最长的子序列长度

滚动dp

python 复制代码
class Solution(object):
    def longestCommonSubsequence(self, text1, text2):
        dp = [0]* (len(text1)+1)
        res = 0
        for i in range(1,len(text2)+1):
            pre = 0
            for j in range(1,len(text1)+1):
                cur = dp[j]
                if text1[j-1] == text2[i-1]:
                    dp[j] = pre + 1
                else:
                    dp[j] = max(dp[j],dp[j-1])
                pre = cur
        return dp[len(text1)]

当使用滚动dp时,就要考虑当前的这个元素和什么有关,如果仅是和上有关,那就可以将dp的内容倒序更新,但是如果和左也有关系,那就只能正序更新,然后记录更新之前的当前元素。

相关推荐
多米Domi0113 小时前
0x3f第14天 最长公共子序列
算法·深度优先
spssau3 小时前
正交试验设计全解析:从正交表生成到极差与方差分析
数据库·算法·机器学习
minhuan3 小时前
大模型应用:不减性能只减负担:大模型稀疏化技术全景与实践.36
大数据·人工智能·算法
爱学大树锯4 小时前
592 · 查找和替换模式
算法
爱学大树锯4 小时前
775 · 回文对
算法
girl-07264 小时前
2025.12.26代码分析
数据结构·算法
大罗辑4 小时前
2026软考备考刷题:软件设计师经典100题(5)含详细解析
算法·软考·软件设计师·2026软考·软设备考
咕噜企业分发小米4 小时前
阿里云Milvus支持哪些向量检索算法?
算法·机器学习·milvus
蒙奇D索大4 小时前
【数据结构】排序算法精讲|折半插入排序全解:高效优化、性能对比、实战剖析
数据结构·学习·考研·算法·排序算法·改行学it
汽车仪器仪表相关领域4 小时前
ZDT-III 通用电机测试系统
数据库·算法·单元测试·压力测试·可用性测试