2022-03-05:不相交的线。 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直

Posted 福大大架构师每日一题

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022-03-05:不相交的线。 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直相关的知识,希望对你有一定的参考价值。

2022-03-05:不相交的线。
在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。
现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足:
nums1[i] == nums2[j]
且绘制的直线不与任何其他连线(非水平线)相交。
请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。
以这种方法绘制线条,并返回可以绘制的最大连线数。
输入:nums1 = [1,4,2], nums2 = [1,2,4]。
输出:2。
解释:可以画出两条不交叉的线,如上图所示。
但无法画出第三条不相交的直线,因为从 nums1[1]=4 到 nums2[2]=4 的直线将与从 nums1[2]=2 到 nums2[1]=2 的直线相交。
力扣1035。

答案2022-03-05:

求最长公共子序列。

代码用golang编写。代码如下:

package main

import "fmt"

func main() 
	if true 
		A := []int1, 4, 2
		B := []int1, 2, 4
		ret := maxUncrossedLines1(A, B)
		fmt.Println(ret)
	
	if true 
		A := []int1, 4, 2
		B := []int1, 2, 4
		ret := maxUncrossedLines2(A, B)
		fmt.Println(ret)
	


// 针对这个题的题意,做的动态规划
func maxUncrossedLines1(A, B []int) int 
	if len(A) == 0 || len(B) == 0 
		return 0
	
	N := len(A)
	M := len(B)
	// dp[i][j]代表: A[0...i]对应B[0...j]最多能划几条线
	dp := make([][]int, N)
	for i := 0; i < N; i++ 
		dp[i] = make([]int, M)
	
	if A[0] == B[0] 
		dp[0][0] = 1
	
	for j := 1; j < M; j++ 
		dp[0][j] = twoSelectOne(A[0] == B[j], 1, dp[0][j-1])
	
	for i := 1; i < N; i++ 
		dp[i][0] = twoSelectOne(A[i] == B[0], 1, dp[i-1][0])
	
	// 某个值(key),上次在A中出现的位置(value)
	AvalueLastIndex := make(map[int]int)
	AvalueLastIndex[A[0]] = 0
	// 某个值(key),上次在B中出现的位置(value)
	BvalueLastIndex := make(map[int]int)
	for i := 1; i < N; i++ 
		AvalueLastIndex[A[i]] = i
		BvalueLastIndex[B[0]] = 0
		for j := 1; j < M; j++ 
			BvalueLastIndex[B[j]] = j
			// 可能性1,就是不让A[i]去划线
			p1 := dp[i-1][j]
			// 可能性2,就是不让B[j]去划线
			p2 := dp[i][j-1]
			// 可能性3,就是要让A[i]去划线,那么如果A[i]==5,它跟谁划线?
			// 贪心的点:一定是在B[0...j]中,尽量靠右侧的5
			p3 := 0
			if _, ok := BvalueLastIndex[A[i]]; ok 
				last := BvalueLastIndex[A[i]]
				p3 = twoSelectOne(last > 0, dp[i-1][last-1], 0) + 1
			
			// 可能性4,就是要让B[j]去划线,那么如果B[j]==7,它跟谁划线?
			// 贪心的点:一定是在A[0...i]中,尽量靠右侧的7
			p4 := 0
			if _, ok := AvalueLastIndex[B[j]]; ok 
				last := AvalueLastIndex[B[j]]
				p4 = twoSelectOne(last > 0, dp[last-1][j-1], 0) + 1
			
			dp[i][j] = getMax(getMax(p1, p2), getMax(p3, p4))
		
		BvalueLastIndex = make(map[int]int)
	
	return dp[N-1][M-1]


// 但是其实这个题,不就是求两个数组的最长公共子序列吗?
func maxUncrossedLines2(A, B []int) int 
	if len(A) == 0 || len(B) == 0 
		return 0
	
	N := len(A)
	M := len(B)
	dp := make([][]int, N)
	for i := 0; i < N; i++ 
		dp[i] = make([]int, M)
	
	dp[0][0] = twoSelectOne(A[0] == B[0], 1, 0)
	for j := 1; j < M; j++ 
		dp[0][j] = twoSelectOne(A[0] == B[j], 1, dp[0][j-1])
	
	for i := 1; i < N; i++ 
		dp[i][0] = twoSelectOne(A[i] == B[0], 1, dp[i-1][0])
	
	for i := 1; i < N; i++ 
		for j := 1; j < M; j++ 
			p1 := dp[i-1][j]
			p2 := dp[i][j-1]
			p3 := twoSelectOne(A[i] == B[j], 1+dp[i-1][j-1], 0)
			dp[i][j] = getMax(p1, getMax(p2, p3))
		
	
	return dp[N-1][M-1]


func twoSelectOne(c bool, a, b int) int 
	if c 
		return a
	 else 
		return b
	


func getMax(a, b int) int 
	if a > b 
		return a
	 else 
		return b
	


执行结果如下:


左神java代码

以上是关于2022-03-05:不相交的线。 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直的主要内容,如果未能解决你的问题,请参考以下文章

leetcode每日一题不相交的线

leetcode1035. 不相交的线DP

#yyds干货盘点# leetcode算法题:不相交的线

LeetCode1035. 不相交的线 / 504. 七进制数 / 315. 计算右侧小于当前元素的个数 / 剑指 Offer 52. 两个链表的第一个公共节点

用VISIO画两条交叉的线,怎样让它们相交处有个小弯

LeetCode篇:1035 不相交的线(JavaScript版)