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

相关推荐
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农1 天前
【React用到的一些算法】游标和栈
算法·react.js
博笙困了1 天前
AcWing学习——双指针算法
c++·算法
moonlifesudo1 天前
322:零钱兑换(三种方法)
算法
NAGNIP2 天前
大模型框架性能优化策略:延迟、吞吐量与成本权衡
算法
美团技术团队2 天前
LongCat-Flash:如何使用 SGLang 部署美团 Agentic 模型
人工智能·算法
Fanxt_Ja2 天前
【LeetCode】算法详解#15 ---环形链表II
数据结构·算法·leetcode·链表
侃侃_天下2 天前
最终的信号类
开发语言·c++·算法