-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path1035.uncrossed-lines.java
More file actions
159 lines (142 loc) · 3.77 KB
/
Copy path1035.uncrossed-lines.java
File metadata and controls
159 lines (142 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
* @lc app=leetcode id=1035 lang=java
*
* [1035] Uncrossed Lines
*
* https://leetcode.com/problems/uncrossed-lines/description/
*
* algorithms
* Medium (51.91%)
* Total Accepted: 10.9K
* Total Submissions: 20.4K
* Testcase Example: '[1,4,2]\n[1,2,4]'
*
* 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
*
*
*
*
*
* Note:
*
*
* 1 <= A.length <= 500
* 1 <= B.length <= 500
* 1 <= A[i], B[i] <= 2000
*
*
*/
class Solution {
public int maxUncrossedLines(int[] A, int[] B) {
if (A.length == 0 || B.length == 0) {
return 0;
}
int alen = A.length;
int blen = B.length;
int[][] dp = new int[alen + 1][blen + 1];
for (int i = 1; i < alen + 1; i++) {
for (int j = 1; j < blen + 1; j++) {
if (A[i - 1] == B[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[alen][blen];
}
// 超时
public int maxUncrossedLines1(int[] A, int[] B) {
if (A.length == 0 || B.length == 0) {
return 0;
}
Map<Integer, Set<Integer>> bMap = new HashMap<>();
for (int i = 0; i < A.length; i++) {
if (!bMap.containsKey(A[i])) {
bMap.put(A[i], new HashSet<>());
}
}
for (int i = 0; i < B.length; i++) {
if (!bMap.containsKey(B[i])) {
continue;
}
bMap.get(B[i]).add(i);
}
return traverse(A, bMap, 0, new LinkedList<>());
}
private int traverse(int[] A, Map<Integer, Set<Integer>> bMap, int start, List<int[]> lines) {
if (start == A.length) {
return 0;
}
int num = A[start];
// starts with the situation no line is connected
int maxLines = traverse(A, bMap, start + 1, lines);
boolean connected = false;
for (int end : bMap.get(num)) {
if (isCrossing(start, end, lines)) {
continue;
}
lines.add(new int[]{start, end});
int res = traverse(A, bMap, start + 1, lines);
if (res >= maxLines) {
connected = true;
maxLines = res;
}
lines.remove(lines.size() - 1);
}
return connected ? maxLines + 1 : maxLines;
}
private boolean isCrossing(int start, int end, List<int[]> lines) {
for (int[] line : lines) {
if ((line[0] > start && line[1] < end) ||
(line[0] < start && line[1] > end) ||
line[0] == start ||
line[1] == end) {
return true;
}
}
return false;
}
}