You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class51;
import java.util.HashMap;
public class Problem_1035_UncrossedLines {
// 针对这个题的题意,做的动态规划
public static int maxUncrossedLines1(int[] A, int[] B) {
if (A == null || A.length == 0 || B == null || B.length == 0) {
return 0;
}
int N = A.length;
int M = B.length;
// dp[i][j]代表: A[0...i]对应B[0...j]最多能划几条线
int[][] dp = new int[N][M];
if (A[0] == B[0]) {
dp[0][0] = 1;
}
for (int j = 1; j < M; j++) {
dp[0][j] = A[0] == B[j] ? 1 : dp[0][j - 1];
}
for (int i = 1; i < N; i++) {
dp[i][0] = A[i] == B[0] ? 1 : dp[i - 1][0];
}
// 某个值(key)上次在A中出现的位置(value)
HashMap<Integer, Integer> AvalueLastIndex = new HashMap<>();
AvalueLastIndex.put(A[0], 0);
// 某个值(key)上次在B中出现的位置(value)
HashMap<Integer, Integer> BvalueLastIndex = new HashMap<>();
for (int i = 1; i < N; i++) {
AvalueLastIndex.put(A[i], i);
BvalueLastIndex.put(B[0], 0);
for (int j = 1; j < M; j++) {
BvalueLastIndex.put(B[j], j);
// 可能性1就是不让A[i]去划线
int p1 = dp[i - 1][j];
// 可能性2就是不让B[j]去划线
int p2 = dp[i][j - 1];
// 可能性3就是要让A[i]去划线那么如果A[i]==5它跟谁划线
// 贪心的点一定是在B[0...j]中尽量靠右侧的5
int p3 = 0;
if (BvalueLastIndex.containsKey(A[i])) {
int last = BvalueLastIndex.get(A[i]);
p3 = (last > 0 ? dp[i - 1][last - 1] : 0) + 1;
}
// 可能性4就是要让B[j]去划线那么如果B[j]==7它跟谁划线
// 贪心的点一定是在A[0...i]中尽量靠右侧的7
int p4 = 0;
if (AvalueLastIndex.containsKey(B[j])) {
int last = AvalueLastIndex.get(B[j]);
p4 = (last > 0 ? dp[last - 1][j - 1] : 0) + 1;
}
dp[i][j] = Math.max(Math.max(p1, p2), Math.max(p3, p4));
}
BvalueLastIndex.clear();
}
return dp[N - 1][M - 1];
}
// 但是其实这个题,不就是求两个数组的最长公共子序列吗?
public static int maxUncrossedLines2(int[] A, int[] B) {
if (A == null || A.length == 0 || B == null || B.length == 0) {
return 0;
}
int N = A.length;
int M = B.length;
int[][] dp = new int[N][M];
dp[0][0] = A[0] == B[0] ? 1 : 0;
for (int j = 1; j < M; j++) {
dp[0][j] = A[0] == B[j] ? 1 : dp[0][j - 1];
}
for (int i = 1; i < N; i++) {
dp[i][0] = A[i] == B[0] ? 1 : dp[i - 1][0];
}
for (int i = 1; i < N; i++) {
for (int j = 1; j < M; j++) {
int p1 = dp[i - 1][j];
int p2 = dp[i][j - 1];
int p3 = A[i] == B[j] ? (1 + dp[i - 1][j - 1]) : 0;
dp[i][j] = Math.max(p1, Math.max(p2, p3));
}
}
return dp[N - 1][M - 1];
}
}