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

给两个整数数组 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 为末尾项的最长公共子数组的长度

相关推荐
CS创新实验室1 小时前
算法、齿轮与硅基大脑:数值计算发展简史
人工智能·算法·数值计算
海石3 小时前
1563分的简单题,可能就简单在能被暴力AC
算法·leetcode
海石3 小时前
1400分的dp汗流浃背之【交替子数组计数】
算法·leetcode
奋发向前wcx3 小时前
P2590 树的统计 题目解析
数据结构·算法·深度优先
imbackneverdie4 小时前
AI4S不止于分子药物:以MedPeer为代表的科研基建打开产业新增量
大数据·人工智能·算法·aigc·科研·学术·ai 4s
额鹅恶饿呃5 小时前
C语言中的数据结构和变量
c语言·数据结构·算法
运行时记录6 小时前
prompt-optimizer skill
算法
万法若空6 小时前
【数据结构-哈希表】哈希表原理
数据结构·算法·散列表
退休倒计时7 小时前
【每日一题】LeetCode 437. 路径总和 III TypeScript
算法·leetcode·typescript
学逆向的7 小时前
汇编——内存
开发语言·汇编·算法·网络安全