STM32驱动AD9910 DDS信号源工程包:带LCD菜单与按键调节,含双中文手册和一键清理脚本
2026/6/8 13:12:02
这两道题名字很像、状态转移很像,但有一个致命区别:
👉是否要求连续。
下面我把它们放在一张笔记里,一次讲透。
| 题号 | 题目 | 是否连续 |
|---|---|---|
| 1143 | 最长公共子序列(LCS) | ❌ 不要求连续 |
| 718 | 最长重复子数组 | ✅ 必须连续 |
给定两个数组 / 字符串,求它们的最长公共部分。
✅ 二维 DP
✅ 面试超级高频
✅ 经典模板题
dp[i][j]=第一个数组前 i 个元素(以i-1结尾) 与第二个数组前 j 个元素(以j-1结尾) 的最长公共长度✅ 使用i、j 从 1 开始
✅ 方便处理边界
if(text1[i-1]==text2[j-1]){dp[i][j]=dp[i-1][j-1]+1;}else{dp[i][j]=max(dp[i-1][j],dp[i][j-1]);}✅ 不相等时:
text1[i]text2[j]if(nums1[i-1]==nums2[j-1]){dp[i][j]=dp[i-1][j-1]+1;}else{dp[i][j]=0;// 必须连续,断了就归零}✅ 不相等时:
classSolution{publicintlongestCommonSubsequence(Stringtext1,Stringtext2){intlen1=text1.length();intlen2=text2.length();char[]t1=text1.toCharArray();char[]t2=text2.toCharArray();int[][]dp=newint[len1+1][len2+1];intres=0;for(inti=1;i<=len1;i++){for(intj=1;j<=len2;j++){if(t1[i-1]==t2[j-1]){dp[i][j]=dp[i-1][j-1]+1;}else{dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);}res=Math.max(res,dp[i][j]);}}returnres;}}classSolution{publicintfindLength(int[]nums1,int[]nums2){intlen1=nums1.length;intlen2=nums2.length;int[][]dp=newint[len1+1][len2+1];intres=0;for(inti=1;i<=len1;i++){for(intj=1;j<=len2;j++){if(nums1[i-1]==nums2[j-1]){dp[i][j]=dp[i-1][j-1]+1;}else{dp[i][j]=0;}res=Math.max(res,dp[i][j]);}}returnres;}}| 对比项 | 1143(LCS) | 718(子数组) |
|---|---|---|
| 是否连续 | ❌ | ✅ |
| 相等时 | dp[i-1][j-1] + 1 | dp[i-1][j-1] + 1 |
| 不相等时 | max(dp[i-1][j], dp[i][j-1]) | 0 |
| 时间复杂度 | O(n²) | O(n²) |
| 指标 | 复杂度 |
|---|---|
| 时间复杂度 | O(len1 × len2) |
| 空间复杂度 | O(len1 × len2) |
LCS 是“可以不连续,断了还能接”;
最长重复子数组是“必须连续,断了就重来”。