-
Notifications
You must be signed in to change notification settings - Fork 22
/
Russian Doll Envelopes.java
executable file
·102 lines (89 loc) · 3.52 KB
/
Russian Doll Envelopes.java
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
H
1523597951
tags: Binary Search, DP, Coordinate DP
俄罗斯套娃, 这里用envelope来表现. 给一串array, 每一个[x, y] 是envelope 长宽. [[5,4],[6,4],[6,7],[2,3]].
看用这些套娃, 可以最多套几个.
#### DP: 1D Coordinate
- envelopes没有顺序, 先排序 (主要根据第一个index排序)
- 然后观察: 排序过后, 就变成了1D的坐标动态规划.
- max number 取决于上一个成功Russian doll的 max value + 1
- 上一个index不知道, 所以遍历找上一个index.
- 当下index i 的状态, 取决于前面index j 的状态, 所以遍历两个index.
- O(n^2)的DP, n = envelopes.length;
#### DP: 2D Coordinate
- 这个方法是自己想出来的, 但是时间复杂度太大, timeout
- 把envelop标记在2D grid上面, 然后像走机器人一样, 求到最右下角的最大 count max.
- count 当下能存在多少Russian doll
- 两种情况: 当下coordinate 没有target, 当下coordinate有target
- 当下coordinate 没有target: 如同机器人走法, Math.max(dp[i - 1][j], dp[i][j - 1])
- 当下coordinate 有target: dp[i - 1][j - 1] + dp[i][j]
- timeout: O(n^2), n = largest coordinate.
```
/*
You have a number of envelopes with widths and heights given as a pair of integers (w, h).
One envelope can fit into another if and only if both the width and height of one envelope
is greater than the width and height of the other envelope.
What is the maximum number of envelopes can you Russian doll? (put one inside other)
Example:
Given envelopes = [[5,4],[6,4],[6,7],[2,3]],
the maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).
*/
// DP, O(n^2), where n = envelopes.length
class Solution {
public int maxEnvelopes(int[][] envelopes) {
if (envelopes == null || envelopes.length == 0
|| envelopes[0] == null || envelopes[0].length == 0) {
return 0;
}
Arrays.sort(envelopes, new Comparator<int[]>() {
public int compare (int[] a, int[] b) {
if (a[0] == b[0]) {
return a[1] - b[1];
} else {
return a[0] - b[0];
}
}
});
int n = envelopes.length;
int[] dp = new int[n];
int max = 0;
for (int i = 0; i < n; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if(envelopes[j][0] < envelopes[i][0] && envelopes[j][1] < envelopes[i][1]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
max = Math.max(max, dp[i]);
}
return max;
}
}
// DP, O(n^2), where n = longest width, timeout
class Solution {
public int maxEnvelopes(int[][] envelopes) {
if (envelopes == null || envelopes.length == 0
|| envelopes[0] == null || envelopes[0].length == 0) {
return 0;
}
// find boundary
int n = 0, m = 0;
for (int[] envelope : envelopes) {
n = Math.max(n, envelope[0]);
m = Math.max(m, envelope[1]);
}
// Mark 1 for existing envelope corrdinate
int[][] dp = new int[n + 1][m + 1];
for (int[] envelope : envelopes) {
dp[envelope[0]][envelope[1]] = 1;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int temp = dp[i][j] == 1 ? dp[i - 1][j - 1] + dp[i][j] : Math.max(dp[i - 1][j], dp[i][j - 1]);
dp[i][j] = Math.max(temp, dp[i][j]);
}
}
return dp[n][m];
}
}
```