LeetCode每日一题-2021/05/21-不相交的线

本文解析了如何将最长公共子序列问题转换为寻找最大无交叉线条的问题,揭示两者间的内在联系。通过动态规划求解策略,详细讲解了如何计算在给定数组nums1和nums2中可以绘制的最大连线数,适合动态规划进阶理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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

仔细读题,会发现一个特别神奇的东西,这道题其实就是最长公共子序列问题换了一种问法,其实换汤不换药,看到这里是不是觉得恍然大悟,如梦初醒呢?

最长公共子序列问题是一道非常经典的动态规划问题,如果最长公共子序列搞懂了,那这道题就不会有任何问题,如果还没搞懂,建议先看看最长公共子序列问题。

代码如下:

class Solution {
    public int maxUncrossedLines(int[] nums1, int[] nums2) {
        int dp[][] = new int[nums2.length][nums1.length];
        // 首先dp数组的第一行第一列
        // 填充第一列
        for( int i = 0; i < dp.length; ++i ){
            if( nums2[i] == nums1[0] ){
                dp[i][0] = 1;
                ++i;
                while( i < dp.length ){
                    dp[i++][0] = 1;
                }
            }
        }
        // 填充第一行
        for( int i = 0; i < dp[0].length; ++i ){
            if( nums1[i] == nums2[0] ){
                dp[0][i] = 1;
                ++i;
                while( i < dp[0].length ){
                    dp[0][i++] = 1;
                }
            }
        }
        // 填充剩下的
        for( int i = 1; i < dp.length; ++i ){
            for( int j = 1; j < dp[0].length; ++j ){
                int temp = dp[i - 1][j - 1];
                if( nums1[j] == nums2[i] ){
                    dp[i][j] = ++temp;
                }else{
                    dp[i][j] = Math.max(dp[i][j - 1],dp[i - 1][j]);
                }
                
            }
        }
        return dp[dp.length - 1][dp[0].length - 1];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值