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

给两个整数数组 nums1nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度

. - 力扣(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 为末尾项的最长公共子数组的长度

相关推荐
圣光SG8 小时前
Java操作题练习(七)
java·开发语言·算法
Cx330_FCQ9 小时前
Tmux使用
服务器·git·算法
拳里剑气10 小时前
C++算法:多源BFS
c++·算法·宽度优先·多源bfs
ysa05103011 小时前
【板子】短序列dp(换成维护更小常数维度的dp)
c++·笔记·算法·板子
shwill12311 小时前
PID 算法(三)--- 增量 PID ↔ 单神经元 PID 等价映射
linux·算法
wabs66612 小时前
关于图论【卡码网110.字符串迁移的思考】
数据结构·算法·图论
hanlin0312 小时前
刷题笔记:力扣第242、349题(哈希表)
笔记·算法·leetcode
浮沉98713 小时前
二分查找算法例题(二)
算法
only-qi14 小时前
大模型Agent面试攻略:落地工程痛点、评估体系与Agentic RAG核心精讲
人工智能·算法·面试·职场和发展·langchain·rag
Gauss松鼠会16 小时前
【GaussDB】GaussDB锁阻塞源头查询
java·开发语言·前端·数据库·算法·gaussdb·经验总结