【LeetCode】1035. 不相交的线

367 阅读2分钟

不相交的线

在两条独立的水平线上按给定的顺序写下nums1和nums2中的整数。

现在,可以绘制一些连接两个数字nums1[i]和nums2[j]的直线,这些直线需要同时满足满足:

nums1[i]==nums2[j] 且绘制的直线不与任何其他连线(非水平线)相交。 请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。

以这种方法绘制线条,并返回可以绘制的最大连线数。

思路

  • 首先分析题目:当nums1[i]==nums2[j],两个数字才可以连线,且该直线不能和其他连线相交,也就说要保持序列的相对顺序。
  • 求最大连线数,也就是求最长子序列长度。
  • 解决最长子序列长度问题最常见的方法是动态规划
  • nums1的长度为m,nums2的长度为n,定义m+1行n+1列的dp二维数组,其中dp[i][j]表示nums1[0:i-1]和nums2[0:j-1]的最长子序列长度。
  • 当nums1[i]==nums2[j]时,dp[i+1][j+1]=dp[i][j]+1
  • 当nums1[i]!=nums2[j]时,可以考虑下面两个场景:nums1[0:i+1]和nums2[0:j] 和nums1[0:i]和nums2[0;j+1]。因此dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1])
  • 综上所述,可以得到状态方程。

示例1

输入:nums1 = [1,4,2], nums2 = [1,2,4]
输出:2
解释:可以画出两条不交叉的线,如上图所示。 
但无法画出第三条不相交的直线,因为从 nums1[1]=4 到 nums2[2]=4 的直线将与从 nums1[2]=2 到 nums2[1]=2 的直线相交。

示例2

输入:nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
输出:3

解法

func maxUncrossedLines(nums1 []int, nums2 []int) int {
    dp:=make([][]int,len(nums1)+1)
    for i:=0;i<len(dp);i++{   // 定义dp二维数组,len(nums1)*len(nums2)
        dp[i]=make([]int,len(nums2)+1)
    }
    for i:=0;i<len(nums1);i++{
        for j:=0;j<len(nums2);j++{
            if nums1[i]==nums2[j]{ // 两元素相等,则nums1[0:i-1]和nums2[0:j-1]的最长子序列长度加1即可。
                dp[i+1][j+1]=dp[i][j]+1
            }else{
                dp[i+1][j+1]=getMaxValue2(dp[i][j+1],dp[i+1][j]) // 上述两类情况的最大值
            }
    }
    return dp[len(nums1)][len(nums2)]
}
func getMaxValue2(a,b int)int{
    if a>b{
            return a
    }
    return b
}