动态规划-1035.不相交的线-力扣(LeetCode)
一、题目解析
光看题目要求和例图,感觉这题好麻烦,直线不能相交啊,每个数字只属于一条连线啊等等,但我们结合题目所给的信息和例图的内容,这不就是最长公共子序列吗?,我们把最长公共子序列连线起来,符合该题要求,由于每个数字只能连一条线,所以这里的公共子序列长度等于不相交的线的条数
二、算法原理
这里详细内容移步我之前的博客动态规划-1143.最长公共子序列-力扣(LeetCode)_lintcode 最长公共子序列-CSDN博客
1、状态表示
dp[i][j]表示:在[0,i]的nums1和[0,j]的nums2所有子序列中最长的公共子序列
2、状态转移方程
根据两个数组最后一个元素划分状态
dp[i][j]->nums1[i]==nums2[j]->dp[i-1][j-1]+1
->nums[i]!=nums2[j]->dp[i-1][j]
->dp[i][j-1]
->dp[i-1][j-1]
由于前两个都包括第三种状态,所以max(dp[i-1][j],dp[i][j-1])
3、初始化
最坏情况为没有最长子序列,所以全初始化为0,且多加一行一列用于初始化,注意下标映射
4、填表顺序
从上往下,从左往右
5、返回值
dp[m][n],m为nums1的长度,n为nums2的长度
建议对最长公共子序列有遗忘的,可以回顾我之前的博客
链接:动态规划-1143.最长公共子序列-力扣(LeetCode)_lintcode 最长公共子序列-CSDN博客
题目链接:1035. 不相交的线 - 力扣(LeetCode)
三、代码示例
class Solution {
public:int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {int m = nums1.size(),n = nums2.size();vector<vector<int>> dp(m+1,vector<int>(n+1,0));for(int i = 1;i<=m;i++){for(int j = 1;j<=n;j++){if(nums1[i-1] == nums2[j-1]){dp[i][j] = dp[i-1][j-1]+1;}else{dp[i][j] = max(dp[i-1][j],dp[i][j-1]);}}}return dp[m][n];}
};
看到最后,如果对您有所帮助,还请点赞、收藏和关注,点点关注不迷路,我们下期再见!