Skip to content

Commit 96cfb3f

Browse files
committed
feat: add solutions to lc problem: No.1691
No.1691.Maximum Height by Stacking Cuboids
1 parent d639ce5 commit 96cfb3f

File tree

7 files changed

+167
-109
lines changed

7 files changed

+167
-109
lines changed

solution/1600-1699/1691.Maximum Height by Stacking Cuboids/README.md

+68-41
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,27 @@
6363

6464
<!-- 这里可写通用的实现逻辑 -->
6565

66-
考虑两个长方体,假设其三边分别是 `(a1, b1, c2)``(a2, b2, c2)`。这里不妨设 `a1≤b1≤c1`, `a2≤b2≤c2`。我们可以发现,假设两个长方体能够拼接到一起(假设第一个长方体较小),则必然有:`a1≤a2, b1≤b2, c1≤c2`
66+
**方法一:排序 + 动态规划**
6767

68-
直观上我们可以发现,如果两个长方体能够拼接到一起,则他们可以从任何一个面进行拼接。本题允许我们任意旋转长方体,看起来情况比较复杂,需要讨论 6 种排列情况,但实际上,因为我们希望高度尽可能高,所以根据上面的观察,我们应该选择**从较短的两条边组成的面**进行拼接
68+
根据题目描述,长方体 $j$ 能够放在长方体 $i$ 上,当且仅当长方体 $j$ 的“长、宽、高”分别小于等于长方体 $i$ 的“长、宽、高”
6969

70-
因此,我们进行两次排序:
70+
本题允许我们旋转长方体,意味着我们可以选择长方体的任意一边作为长方体的“高”。对于任意一种合法的堆叠,如果我们把里面每个长方体都旋转至“长 <= 宽 <= 高”,堆叠仍然是合法的,并且能够保证堆叠的高度最大化。
7171

72-
1. 将每个长方体的三条边按升序排列;
73-
1. 将每个长方体升序排列。
72+
因此,我们可以把所有长方体的边长进行排序,使得每个长方体满足“长 <= 宽 <= 高”。然后将每个长方体升序排列。
7473

75-
之后,问题转换为最长上升子序列问题。对于第 i 个长方体,我们依次考虑第 `[1...i-1]` 个长方体,看能否将第 i 个长方体拼接在它的下方,然后更新当前的最大值
74+
接下来,我们可以使用动态规划的方法求解本题
7675

77-
时间复杂度 $O(n^2)$。
76+
我们定义 $f[i]$ 表示以长方体 $i$ 为最底部长方体时的最大高度。我们可以枚举每个长方体 $i$ 的上方的长方体 $j$,如果 $j$ 可以放在 $i$ 的上方,那么我们可以得到状态转移方程:
77+
78+
$$
79+
f[i] = \max(f[i], f[j] + h[i])
80+
$$
81+
82+
其中 $h[i]$ 表示长方体 $i$ 的高度。
83+
84+
最终的答案即为 $f[i]$ 的最大值。
85+
86+
时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为长方体的数量。
7887

7988
<!-- tabs:start -->
8089

@@ -89,13 +98,13 @@ class Solution:
8998
c.sort()
9099
cuboids.sort()
91100
n = len(cuboids)
92-
dp = [0] * n
101+
f = [0] * n
93102
for i in range(n):
94103
for j in range(i):
95104
if cuboids[j][1] <= cuboids[i][1] and cuboids[j][2] <= cuboids[i][2]:
96-
dp[i] = max(dp[i], dp[j])
97-
dp[i] += cuboids[i][2]
98-
return max(dp)
105+
f[i] = max(f[i], f[j])
106+
f[i] += cuboids[i][2]
107+
return max(f)
99108
```
100109

101110
### **Java**
@@ -105,31 +114,21 @@ class Solution:
105114
```java
106115
class Solution {
107116
public int maxHeight(int[][] cuboids) {
108-
for (int[] c : cuboids) {
117+
for (var c : cuboids) {
109118
Arrays.sort(c);
110119
}
111-
Arrays.sort(cuboids, (a, b) -> {
112-
if (a[0] != b[0]) {
113-
return a[0] - b[0];
114-
}
115-
if (a[1] != b[1]) {
116-
return a[1] - b[1];
117-
}
118-
return a[2] - b[2];
119-
});
120+
Arrays.sort(cuboids, (a, b) -> a[0] == b[0] ? (a[1] == b[1] ? a[2] - b[2] : a[1] - b[1]) : a[0] - b[0]);
120121
int n = cuboids.length;
121-
int[] dp = new int[n];
122-
int ans = 0;
122+
int[] f = new int[n];
123123
for (int i = 0; i < n; ++i) {
124124
for (int j = 0; j < i; ++j) {
125125
if (cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2]) {
126-
dp[i] = Math.max(dp[i], dp[j]);
126+
f[i] = Math.max(f[i], f[j]);
127127
}
128128
}
129-
dp[i] += cuboids[i][2];
130-
ans = Math.max(ans, dp[i]);
129+
f[i] += cuboids[i][2];
131130
}
132-
return ans;
131+
return Arrays.stream(f).max().getAsInt();
133132
}
134133
}
135134
```
@@ -143,26 +142,24 @@ public:
143142
for (auto& c : cuboids) sort(c.begin(), c.end());
144143
sort(cuboids.begin(), cuboids.end());
145144
int n = cuboids.size();
146-
vector<int> dp(n);
147-
int ans = 0;
145+
vector<int> f(n);
148146
for (int i = 0; i < n; ++i) {
149147
for (int j = 0; j < i; ++j) {
150148
if (cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2]) {
151-
dp[i] = max(dp[i], dp[j]);
149+
f[i] = max(f[i], f[j]);
152150
}
153151
}
154-
dp[i] += cuboids[i][2];
155-
ans = max(ans, dp[i]);
152+
f[i] += cuboids[i][2];
156153
}
157-
return ans;
154+
return *max_element(f.begin(), f.end());
158155
}
159156
};
160157
```
161158
162159
### **Go**
163160
164161
```go
165-
func maxHeight(cuboids [][]int) int {
162+
func maxHeight(cuboids [][]int) (ans int) {
166163
for _, c := range cuboids {
167164
sort.Ints(c)
168165
}
@@ -176,18 +173,17 @@ func maxHeight(cuboids [][]int) int {
176173
return cuboids[i][2] < cuboids[j][2]
177174
})
178175
n := len(cuboids)
179-
dp := make([]int, n)
180-
ans := 0
181-
for i := 0; i < n; i++ {
176+
f := make([]int, n)
177+
for i := range f {
182178
for j := 0; j < i; j++ {
183179
if cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2] {
184-
dp[i] = max(dp[i], dp[j])
180+
f[i] = max(f[i], f[j])
185181
}
186182
}
187-
dp[i] += cuboids[i][2]
188-
ans = max(ans, dp[i])
183+
f[i] += cuboids[i][2]
184+
ans = max(ans, f[i])
189185
}
190-
return ans
186+
return
191187
}
192188
193189
func max(a, b int) int {
@@ -198,6 +194,37 @@ func max(a, b int) int {
198194
}
199195
```
200196

197+
### **JavaScript**
198+
199+
```js
200+
/**
201+
* @param {number[][]} cuboids
202+
* @return {number}
203+
*/
204+
var maxHeight = function (cuboids) {
205+
for (const c of cuboids) {
206+
c.sort((a, b) => a - b);
207+
}
208+
cuboids.sort((a, b) => {
209+
if (a[0] != b[0]) return a[0] - b[0];
210+
if (a[1] != b[1]) return a[1] - b[1];
211+
return a[2] - b[2];
212+
});
213+
const n = cuboids.length;
214+
const f = new Array(n).fill(0);
215+
for (let i = 0; i < n; ++i) {
216+
for (let j = 0; j < i; ++j) {
217+
const ok =
218+
cuboids[j][1] <= cuboids[i][1] &&
219+
cuboids[j][2] <= cuboids[i][2];
220+
if (ok) f[i] = Math.max(f[i], f[j]);
221+
}
222+
f[i] += cuboids[i][2];
223+
}
224+
return Math.max(...f);
225+
};
226+
```
227+
201228
### **...**
202229

203230
```

solution/1600-1699/1691.Maximum Height by Stacking Cuboids/README_EN.md

+52-34
Original file line numberDiff line numberDiff line change
@@ -68,45 +68,35 @@ class Solution:
6868
c.sort()
6969
cuboids.sort()
7070
n = len(cuboids)
71-
dp = [0] * n
71+
f = [0] * n
7272
for i in range(n):
7373
for j in range(i):
7474
if cuboids[j][1] <= cuboids[i][1] and cuboids[j][2] <= cuboids[i][2]:
75-
dp[i] = max(dp[i], dp[j])
76-
dp[i] += cuboids[i][2]
77-
return max(dp)
75+
f[i] = max(f[i], f[j])
76+
f[i] += cuboids[i][2]
77+
return max(f)
7878
```
7979

8080
### **Java**
8181

8282
```java
8383
class Solution {
8484
public int maxHeight(int[][] cuboids) {
85-
for (int[] c : cuboids) {
85+
for (var c : cuboids) {
8686
Arrays.sort(c);
8787
}
88-
Arrays.sort(cuboids, (a, b) -> {
89-
if (a[0] != b[0]) {
90-
return a[0] - b[0];
91-
}
92-
if (a[1] != b[1]) {
93-
return a[1] - b[1];
94-
}
95-
return a[2] - b[2];
96-
});
88+
Arrays.sort(cuboids, (a, b) -> a[0] == b[0] ? (a[1] == b[1] ? a[2] - b[2] : a[1] - b[1]) : a[0] - b[0]);
9789
int n = cuboids.length;
98-
int[] dp = new int[n];
99-
int ans = 0;
90+
int[] f = new int[n];
10091
for (int i = 0; i < n; ++i) {
10192
for (int j = 0; j < i; ++j) {
10293
if (cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2]) {
103-
dp[i] = Math.max(dp[i], dp[j]);
94+
f[i] = Math.max(f[i], f[j]);
10495
}
10596
}
106-
dp[i] += cuboids[i][2];
107-
ans = Math.max(ans, dp[i]);
97+
f[i] += cuboids[i][2];
10898
}
109-
return ans;
99+
return Arrays.stream(f).max().getAsInt();
110100
}
111101
}
112102
```
@@ -120,26 +110,24 @@ public:
120110
for (auto& c : cuboids) sort(c.begin(), c.end());
121111
sort(cuboids.begin(), cuboids.end());
122112
int n = cuboids.size();
123-
vector<int> dp(n);
124-
int ans = 0;
113+
vector<int> f(n);
125114
for (int i = 0; i < n; ++i) {
126115
for (int j = 0; j < i; ++j) {
127116
if (cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2]) {
128-
dp[i] = max(dp[i], dp[j]);
117+
f[i] = max(f[i], f[j]);
129118
}
130119
}
131-
dp[i] += cuboids[i][2];
132-
ans = max(ans, dp[i]);
120+
f[i] += cuboids[i][2];
133121
}
134-
return ans;
122+
return *max_element(f.begin(), f.end());
135123
}
136124
};
137125
```
138126
139127
### **Go**
140128
141129
```go
142-
func maxHeight(cuboids [][]int) int {
130+
func maxHeight(cuboids [][]int) (ans int) {
143131
for _, c := range cuboids {
144132
sort.Ints(c)
145133
}
@@ -153,18 +141,17 @@ func maxHeight(cuboids [][]int) int {
153141
return cuboids[i][2] < cuboids[j][2]
154142
})
155143
n := len(cuboids)
156-
dp := make([]int, n)
157-
ans := 0
158-
for i := 0; i < n; i++ {
144+
f := make([]int, n)
145+
for i := range f {
159146
for j := 0; j < i; j++ {
160147
if cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2] {
161-
dp[i] = max(dp[i], dp[j])
148+
f[i] = max(f[i], f[j])
162149
}
163150
}
164-
dp[i] += cuboids[i][2]
165-
ans = max(ans, dp[i])
151+
f[i] += cuboids[i][2]
152+
ans = max(ans, f[i])
166153
}
167-
return ans
154+
return
168155
}
169156
170157
func max(a, b int) int {
@@ -175,6 +162,37 @@ func max(a, b int) int {
175162
}
176163
```
177164

165+
### **JavaScript**
166+
167+
```js
168+
/**
169+
* @param {number[][]} cuboids
170+
* @return {number}
171+
*/
172+
var maxHeight = function (cuboids) {
173+
for (const c of cuboids) {
174+
c.sort((a, b) => a - b);
175+
}
176+
cuboids.sort((a, b) => {
177+
if (a[0] != b[0]) return a[0] - b[0];
178+
if (a[1] != b[1]) return a[1] - b[1];
179+
return a[2] - b[2];
180+
});
181+
const n = cuboids.length;
182+
const f = new Array(n).fill(0);
183+
for (let i = 0; i < n; ++i) {
184+
for (let j = 0; j < i; ++j) {
185+
const ok =
186+
cuboids[j][1] <= cuboids[i][1] &&
187+
cuboids[j][2] <= cuboids[i][2];
188+
if (ok) f[i] = Math.max(f[i], f[j]);
189+
}
190+
f[i] += cuboids[i][2];
191+
}
192+
return Math.max(...f);
193+
};
194+
```
195+
178196
### **...**
179197

180198
```

solution/1600-1699/1691.Maximum Height by Stacking Cuboids/Solution.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,15 @@ class Solution {
44
for (auto& c : cuboids) sort(c.begin(), c.end());
55
sort(cuboids.begin(), cuboids.end());
66
int n = cuboids.size();
7-
vector<int> dp(n);
8-
int ans = 0;
7+
vector<int> f(n);
98
for (int i = 0; i < n; ++i) {
109
for (int j = 0; j < i; ++j) {
1110
if (cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2]) {
12-
dp[i] = max(dp[i], dp[j]);
11+
f[i] = max(f[i], f[j]);
1312
}
1413
}
15-
dp[i] += cuboids[i][2];
16-
ans = max(ans, dp[i]);
14+
f[i] += cuboids[i][2];
1715
}
18-
return ans;
16+
return *max_element(f.begin(), f.end());
1917
}
2018
};

solution/1600-1699/1691.Maximum Height by Stacking Cuboids/Solution.go

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
func maxHeight(cuboids [][]int) int {
1+
func maxHeight(cuboids [][]int) (ans int) {
22
for _, c := range cuboids {
33
sort.Ints(c)
44
}
@@ -12,18 +12,17 @@ func maxHeight(cuboids [][]int) int {
1212
return cuboids[i][2] < cuboids[j][2]
1313
})
1414
n := len(cuboids)
15-
dp := make([]int, n)
16-
ans := 0
17-
for i := 0; i < n; i++ {
15+
f := make([]int, n)
16+
for i := range f {
1817
for j := 0; j < i; j++ {
1918
if cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2] {
20-
dp[i] = max(dp[i], dp[j])
19+
f[i] = max(f[i], f[j])
2120
}
2221
}
23-
dp[i] += cuboids[i][2]
24-
ans = max(ans, dp[i])
22+
f[i] += cuboids[i][2]
23+
ans = max(ans, f[i])
2524
}
26-
return ans
25+
return
2726
}
2827

2928
func max(a, b int) int {

0 commit comments

Comments
 (0)