Leetcode May Challenge - 05/25: Uncrossed Lines(Python)

题目描述

We write the integers of A and B (in the order they are given) on two separate horizontal lines.

Now, we may draw connecting lines: a straight line connecting two numbers A[i] and B[j] such that:
A[i] == B[j];
The line we draw does not intersect any other connecting (non-horizontal) line.

Note that a connecting lines cannot intersect even at the endpoints: each number can only belong to one connecting line.

Return the maximum number of connecting lines we can draw in this way.

例子

Example 1:

Input: A = [1,4,2], B = [1,2,4]
Output: 2
Explanation: We can draw 2 uncrossed lines as in the diagram.
We cannot draw 3 uncrossed lines, because the line from A[1]=4 to B[2]=4 will intersect the line from A[2]=2 to B[1]=2.

Example 2:

Input: A = [2,5,1,2,5], B = [10,5,2,1,5,2]
Output: 3

Example 3:

Input: A = [1,3,7,1,7,5], B = [1,9,2,5,1]
Output: 2

解释

给A和B两个一维数组,里面的每个数字表示线段的一个端点。我们每次可以把A和B中数组相同的两个点连接起来。问最多可以连多少条不相交的线段。注意,一个端点只能用一次,否则也视为相交。

思路 动态规划

我们用一个dp的二维数组去存我们所需要的最大的不相交的线段数。dp(i, j)表示在A[:i]和B[:j]的最大不相交线段数。
那么怎么求状态转移方程呢?在i, j这个点,如果恰好A[i] = B[j],则我们直接把dp[i - 1][j - 1]的值再加上1即可。这是因为 dp[i - 1][j - 1]表示的线段的端点均为i,j之前的点因此将i, j连线必不会和之前的线段相交。而如果A[i] != B[j],则dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]),这是因为我们无法将这两个点连线,又需要保留之前的数值为下一个i, j键值对做判断,所以当然就把之前可能的最大值拿过来就好。

代码

class Solution(object):
    def maxUncrossedLines(self, A, B):
        """
        :type A: List[int]
        :type B: List[int]
        :rtype: int
        """
        m, n = len(A), len(B)
        A1, B1 = [0] + A, [0] + B
        dp = [[0] * (n + 1) for i in range(m + 1)]
        for i in range(1, m + 1):
            for j in range(1,n + 1):
                if A1[i] == B1[j]:
                    dp[i][j] = 1 + dp[i - 1][j - 1]
                else:
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
        return dp[-1][-1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值