代码随想录算法训练营第五十天| 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

只要dpij是由dpi-1j或者dpi-1j-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)]

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

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

但是子序列就不一样了,如果dpij不能由dpi-1j-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的内容倒序更新,但是如果和左也有关系,那就只能正序更新,然后记录更新之前的当前元素。

相关推荐
Jerry10 小时前
LeetCode 151. 反转字符串中的单词
算法
a11177613 小时前
LM 算法迭代过程动画演示(SLAM)
算法
头茬韭菜13 小时前
Context 的生死抉择:四层压缩、截断算法与 Session Memory
算法·ai
Jerry13 小时前
LeetCode 541. 反转字符串 II
算法
Jerry13 小时前
LeetCode 344. 反转字符串
算法
搞科研的小刘选手14 小时前
【香港大学主办&IEEE出版】第六届计算机视觉、应用与算法国际学术会议(CVAA 2026)
算法·计算机视觉·应用·学术会议
Java小白笔记14 小时前
Codex config.toml配置实战指南
人工智能·算法·chatgpt·ai编程·集成学习
王老师青少年编程14 小时前
2026年6月GESP真题及题解(C++七级):消消乐
数据结构·c++·算法·真题·gesp·2026年6月
z小猫不吃鱼14 小时前
模型剪枝经典论文精读:Pruning Filters for Efficient ConvNets
算法·机器学习·剪枝
Fox爱分享16 小时前
字节二面:1000瓶酒,有一瓶是毒药,多少只老鼠可以查出来?
算法·面试·程序员