代码随想录算法训练营第五十天| 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的内容倒序更新,但是如果和左也有关系,那就只能正序更新,然后记录更新之前的当前元素。

相关推荐
超级码力6663 小时前
【Latex文件架构】Latex文件架构模板
算法·数学建模·信息可视化
穿条秋裤到处跑3 小时前
每日一道leetcode(2026.04.29):二维网格图中探测环
算法·leetcode·职场和发展
Merlos_wind4 小时前
HashMap详解
算法·哈希算法·散列表
汉克老师4 小时前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
Yzzz-F7 小时前
Problem - 2205D - Codeforces
算法
智者知已应修善业7 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
Halo_tjn7 小时前
Java Set集合相关知识点
java·开发语言·算法
生成论实验室8 小时前
《事件关系阴阳博弈动力学:识势应势之道》第四篇:降U动力学——认知确定度的自驱演化
人工智能·科技·神经网络·算法·架构
AI科技星8 小时前
全域数学·72分册:场计算机卷【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算
科研前沿9 小时前
镜像孪生VS视频孪生核心技术产品核心优势
大数据·人工智能·算法·重构·空间计算