作者:MJ昊
公众号:程序猿的编程之路
今天是 昊 的算法之路第14天,今天分享的是LeetCode第1035题不相交的线的解题思路。这是一道中等难度的动态规划题目,类似于最长公共子序列问题。
题目描述简要回顾
给定两个整数数组 nums1 和 nums2,可以将它们的元素在不改变顺序的情况下配对。配对后需要确保连接线不相交,求最多能画出的不相交线的数量。
解题思路
我们可以将此问题转化为**最长公共子序列(LCS)**问题:
- 如果两个元素相等,就能多画一条线,并且继续向前处理剩下的元素。
- 如果不相等,则需要比较去掉一个元素后的结果,取其中较大的值。
动态规划状态转移方程
设 dp[i][j] 表示使用数组 nums1 的前 i 个元素和 nums2 的前 j 个元素能画出的最大不相交线数量:
- 若
nums1[i - 1] === nums2[j - 1],则dp[i][j] = dp[i - 1][j - 1] + 1。 - 若不相等,则
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])。
代码实现:
var maxUncrossedLines = function(nums1, nums2) {
const dp = new Array(nums1.length + 1).fill(0).map(() => new Array(nums2.length + 1).fill(0));
for (let i = 1; i <= nums1.length; i++) {
for (let j = 1; j <= nums2.length; j++) {
if (nums1[i - 1] === nums2[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]);
}
}
}
return dp[nums1.length][nums2.length];
};
复杂度分析
-
时间复杂度:
O(m * n),其中m和n是nums1和nums2的长度。我们需要遍历整个二维数组。 -
空间复杂度:
O(m * n),用于存储二维数组dp。
总结
这道题通过动态规划巧妙地解决了配对元素的问题。由于类似于最长公共子序列问题,因此掌握了该题的解法后,能帮助理解其他相关的动态规划题目。