算法——最长重复子数组(动态规划)

给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度。

. - 力扣(LeetCode)

方法:动态规划.

dpij 表示,第一个数组的索引i与第二个数组索引j所在位置的元素,从两个数组该位置开始一直到最后相同元素的最大长度。显然如果该位置二者不相等则dp数组值为0.若相等,则weidpi+1j+1+1,即该位置相等,至少为1,加上二者后一个位置的最大长度。这就是状态转移方程。

官方代码一如既往的精简。

在申请数组时多申请一行一列,且赋值为零,在正常范围内计算时如果需要加上也是加上零,无影响。代码精炼,赞。

在涉及到边界条件且与内部情况不一致时,可以添加外层边界,让边界参与同样的计算。(链表增加虚拟头结点也是这样的原理)

复制代码
class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int n = A.size(), m = B.size();
        vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
        int ans = 0;
        for (int i = n - 1; i >= 0; i--) {
            for (int j = m - 1; j >= 0; j--) {
                dp[i][j] = A[i] == B[j] ? dp[i + 1][j + 1] + 1 : 0;
                ans = max(ans, dp[i][j]);
            }
        }
        return ans;
    }
};

附上菜鸡自己的:(原来二维vector数组也是可以直接初始化的)

复制代码
class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        vector<vector<int>>dp(nums1.size());
        int maxlen=INT_MIN;
        for(int i=0;i<nums1.size();i++)
        {
            dp[i].resize(nums2.size());
        }
        for(int i=0;i<nums1.size();i++)
        {
            dp[i][nums2.size()-1]=(nums1[i]==nums2[nums2.size()-1]?1:0);
            if(dp[i][nums2.size()-1]==1)maxlen=1;
        }
        for(int i=0;i<nums2.size();i++)
        {
            dp[nums1.size()-1][i]=(nums1[nums1.size()-1]==nums2[i]?1:0);
            if(dp[nums1.size()-1][i]==1)maxlen=1;
        }
        for(int i=nums1.size()-2;i>=0;i--)
        {
            for(int j=nums2.size()-2;j>=0;j--)
            {
                if(nums1[i]==nums2[j])
                {
                    dp[i][j]=dp[i+1][j+1]+1;
                    maxlen=max(maxlen,dp[i][j]);
                }
                else
                {
                    dp[i][j]=0;
                    maxlen=max(maxlen,dp[i][j]);
                }
            }
        }
        return maxlen;
    }
};

附:可降维优化为一维dp数组。(未尝试)

降维优化

dpij 只依赖上一行上一列的对角线的值,所以我们从右上角开始计算。

一维数组 dp , dpj 是以 Ai-1, Bj-1 为末尾项的最长公共子数组的长度

相关推荐
Pniubi1 分钟前
力扣73 矩阵置零
算法·leetcode·矩阵
布莱克60510 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
D e re k ZH13 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
石小石Orz14 小时前
AI 正在蚕食我们的编码能力
前端·后端·算法
民乐团扒谱机15 小时前
【微实验】NSGA-II(非支配排序遗传算法)——解决多目标优化问题的“自然选择模拟器”
linux·人工智能·算法
青少儿编程课堂16 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:中缀表达式求值解析
c++·python·算法·bfs·信息学竞赛
武子康18 小时前
Qwen-Drive 到底是什么:4B 级 VLM 如何成为驾驶策略底座
人工智能·算法·机器学习
zh_xuan19 小时前
LeeCode 496. 下一个更大元素I
数据结构·算法·栈·单调栈
机 _ 长19 小时前
05 智算运维|8 张卡怎么才算「捆成一张」:NCCL 实测与拓扑
运维·人工智能·算法·智算运维