1、描述
在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。
现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足:
nums1[i] == nums2[j]
且绘制的直线不与任何其他连线(非水平线)相交。
请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。
以这种方法绘制线条,并返回可以绘制的最大连线数。
来源:力扣(LeetCode)
链接
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2、关键字
两个数组,无序,不相交,相等连线,
3、思路
转化成非连续,求最长公共子序列问题,动态规划,
原型
4、notes
1、把这个问题联想转化到求两个字符串的非连续最长公共子串的问题,
2、初始化这个二维表的时候,可以首先把第一行第一列的那个值确定,然后再确定第一行,和第一列,
dp[0][0]=(text1[0]==text2[0])?1:0;
for(int i=1;i<n;i++){ // 初始化第一行
if(dp[0][i-1]==1 || text1[i]==text2[0]){
dp[0][i]=1;
}
res=max(res,dp[0][i]); // 如果是单行也能有结果
}
//方式二
for(int i = 0; i < n1; i++){
// if(nums2[0] == nums1[i]){ // 这样写过不去,
if(nums2[0] == nums1[i] ||(i>0 && res[0][i-1] == 1)){
res[0][i] = 1;
}
if(cnt < res[0][i]){
cnt =res[0][i];
}
}
5、复杂度
时间:O(mN)
空间:O(NM)
6、code
class Solution {
public:
int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
int n1 = nums1.size();
int n2 = nums2.size();
int cnt = 0;
vector<vector<int>>res(n2,vector<int>(n1,0));
for(int i = 0; i < n1; i++){
// if(nums2[0] == nums1[i]){ // 这样写过不去,
if(nums2[0] == nums1[i] ||(i>0 && res[0][i-1] == 1)){
res[0][i] = 1;
}
if(cnt < res[0][i]){
cnt =res[0][i];
}
}
for (int j = 0; j < n2; j++){
if(nums1[0] == nums2[j] || (j >0 && res[j -1 ][0] == 1)){
res[j][0] = 1;
}
if(cnt < res[j][0]){
cnt = res[j][0];
}
}
for(int i = 1; i < n2; i++){
for (int j = 1; j < n1; j++){
if(nums1[j] == nums2[i]){
res[i][j] = res[i - 1][j - 1] +1;
}
else{
res[i][j] = max (res[i - 1][j],res[i][j -1]);
}
if(cnt < res[i][j]){
cnt = res[i][j];
}
}
}
return cnt;
}
};
,