Skip to content

Commit 2aa9df3

Browse files
committed
feat: add solutions to lc problem: No.1130
No.1130.Minimum Cost Tree From Leaf Values
1 parent b8ead96 commit 2aa9df3

File tree

6 files changed

+618
-0
lines changed

6 files changed

+618
-0
lines changed

solution/1100-1199/1130.Minimum Cost Tree From Leaf Values/README.md

+263
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,285 @@
4545

4646
<!-- 这里可写通用的实现逻辑 -->
4747

48+
**方法一:记忆化搜索**
49+
50+
根据题目描述,数组 $arr$ 中的值与树的中序遍历中每个叶节点的值一一对应,因此可以将数组 $arr$ 中的值看作是树的叶节点,我们可以将数组划分为左右两个子数组,分别对应树的左右子树,递归地每个子树的所有非叶子节点的值的最小可能总和。
51+
52+
我们设计一个函数 $dfs(i, j)$,表示数组 $arr$ 中下标范围 $[i, j]$ 内的所有叶节点的值的最小可能总和,那么答案就是 $dfs(0, n - 1)$,其中 $n$ 为数组 $arr$ 的长度。
53+
54+
函数 $dfs(i, j)$ 的计算过程如下:
55+
56+
- 如果 $i = j$,说明数组 $arr$ 中只有一个元素,因此 $dfs(i, j) = 0$。
57+
- 否则,我们枚举 $k \in [i, j - 1]$,将数组 $arr$ 划分为两个子数组 $arr[i \cdots k]$ 和 $arr[k + 1 \cdots j]$,对于每个 $k$,我们计算 $dfs(i, k)$ 和 $dfs(k + 1, j)$,其中 $dfs(i, k)$ 表示数组 $arr$ 中下标范围 $[i, k]$ 内的所有叶节点的值的最小可能总和,而 $dfs(k + 1, j)$ 表示数组 $arr$ 中下标范围 $[k + 1, j]$ 内的所有叶节点的值的最小可能总和,那么 $dfs(i, j) = \min_{i \leq k < j} \{dfs(i, k) + dfs(k + 1, j) + \max_{i \leq t \leq k} \{arr[t]\} \max_{k < t \leq j} \{arr[t]\}\}$。
58+
59+
上述递归过程中,我们可以使用记忆化搜索的方法进行优化,避免重复计算。
60+
61+
最后,我们返回 $dfs(0, n - 1)$ 即可。
62+
63+
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为数组 $arr$ 的长度。
64+
65+
**方法二:动态规划**
66+
67+
我们可以将方法一中的记忆化搜索改为动态规划的方式进行求解。
68+
69+
定义 $f[i][j]$ 表示数组 $arr$ 中下标范围 $[i, j]$ 内的所有叶节点的值的最小可能总和,而 $g[i][j]$ 表示数组 $arr$ 中下标范围 $[i, j]$ 内的所有叶节点的最大值,那么 $f[i][j] = \min_{i \leq k < j} \{f[i][k] + f[k + 1][j] + g[i][k] \cdot g[k + 1][j]\}$,其中 $g[i][j] = \max_{i \leq k \leq j} \{arr[k]\}$。
70+
71+
最后,我们返回 $f[0][n - 1]$ 即可。
72+
73+
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为数组 $arr$ 的长度。
74+
4875
<!-- tabs:start -->
4976

5077
### **Python3**
5178

5279
<!-- 这里可写当前语言的特殊实现逻辑 -->
5380

5481
```python
82+
class Solution:
83+
def mctFromLeafValues(self, arr: List[int]) -> int:
84+
@cache
85+
def dfs(i: int, j: int):
86+
if i == j:
87+
return 0, arr[i]
88+
s, mx = inf, -1
89+
for k in range(i, j):
90+
s1, mx1 = dfs(i, k)
91+
s2, mx2 = dfs(k + 1, j)
92+
t = s1 + s2 + mx1 * mx2
93+
if s > t:
94+
s = t
95+
mx = max(mx1, mx2)
96+
return s, mx
5597

98+
return dfs(0, len(arr) - 1)[0]
99+
```
100+
101+
```python
102+
class Solution:
103+
def mctFromLeafValues(self, arr: List[int]) -> int:
104+
n = len(arr)
105+
f = [[0] * n for _ in range(n)]
106+
g = [[0] * n for _ in range(n)]
107+
for i in range(n):
108+
g[i][i] = arr[i]
109+
for j in range(i + 1, n):
110+
g[i][j] = max(g[i][j - 1], arr[j])
111+
for i in range(n - 1, -1, -1):
112+
for j in range(i + 1, n):
113+
f[i][j] = inf
114+
for k in range(i, j):
115+
f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + g[i][k] * g[k + 1][j])
116+
return f[0][n - 1]
56117
```
57118

58119
### **Java**
59120

60121
<!-- 这里可写当前语言的特殊实现逻辑 -->
61122

62123
```java
124+
class Solution {
125+
private Integer[][] f;
126+
private int[][] g;
127+
128+
public int mctFromLeafValues(int[] arr) {
129+
int n = arr.length;
130+
f = new Integer[n][n];
131+
g = new int[n][n];
132+
for (int i = 0; i < n; i++) {
133+
g[i][i] = arr[i];
134+
for (int j = i + 1; j < n; j++) {
135+
g[i][j] = Math.max(g[i][j - 1], arr[j]);
136+
}
137+
}
138+
return dfs(0, n - 1);
139+
}
140+
141+
private int dfs(int i, int j) {
142+
if (i == j) {
143+
return 0;
144+
}
145+
if (f[i][j] != null) {
146+
return f[i][j];
147+
}
148+
int ans = 1 << 30;
149+
for (int k = i; k < j; k++) {
150+
ans = Math.min(ans, dfs(i, k) + dfs(k + 1, j) + g[i][k] * g[k + 1][j]);
151+
}
152+
return f[i][j] = ans;
153+
}
154+
}
155+
```
156+
157+
```java
158+
class Solution {
159+
public int mctFromLeafValues(int[] arr) {
160+
int n = arr.length;
161+
int[][] f = new int[n][n];
162+
int[][] g = new int[n][n];
163+
for (int i = 0; i < n; ++i) {
164+
g[i][i] = arr[i];
165+
for (int j = i + 1; j < n; ++j) {
166+
g[i][j] = Math.max(g[i][j - 1], arr[j]);
167+
}
168+
}
169+
for (int i = n - 2; i >= 0; --i) {
170+
for (int j = i + 1; j < n; ++j) {
171+
f[i][j] = 1 << 30;
172+
for (int k = i; k < j; ++k) {
173+
f[i][j] = Math.min(f[i][j], f[i][k] + f[k + 1][j] + g[i][k] * g[k + 1][j]);
174+
}
175+
}
176+
}
177+
return f[0][n - 1];
178+
}
179+
}
180+
```
181+
182+
### **C++**
183+
184+
```cpp
185+
class Solution {
186+
public:
187+
int mctFromLeafValues(vector<int>& arr) {
188+
int n = arr.size();
189+
int f[n][n];
190+
int g[n][n];
191+
memset(f, 0, sizeof(f));
192+
for (int i = 0; i < n; ++i) {
193+
g[i][i] = arr[i];
194+
for (int j = i + 1; j < n; ++j) {
195+
g[i][j] = max(g[i][j - 1], arr[j]);
196+
}
197+
}
198+
function<int(int, int)> dfs = [&](int i, int j) -> int {
199+
if (i == j) {
200+
return 0;
201+
}
202+
if (f[i][j] > 0) {
203+
return f[i][j];
204+
}
205+
int ans = 1 << 30;
206+
for (int k = i; k < j; ++k) {
207+
ans = min(ans, dfs(i, k) + dfs(k + 1, j) + g[i][k] * g[k + 1][j]);
208+
}
209+
return f[i][j] = ans;
210+
};
211+
return dfs(0, n - 1);
212+
}
213+
};
214+
```
215+
216+
```cpp
217+
class Solution {
218+
public:
219+
int mctFromLeafValues(vector<int>& arr) {
220+
int n = arr.size();
221+
int f[n][n];
222+
int g[n][n];
223+
memset(f, 0, sizeof(f));
224+
for (int i = 0; i < n; ++i) {
225+
g[i][i] = arr[i];
226+
for (int j = i + 1; j < n; ++j) {
227+
g[i][j] = max(g[i][j - 1], arr[j]);
228+
}
229+
}
230+
for (int i = n - 2; ~i; --i) {
231+
for (int j = i + 1; j < n; ++j) {
232+
f[i][j] = 1 << 30;
233+
for (int k = i; k < j; ++k) {
234+
f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + g[i][k] * g[k + 1][j]);
235+
}
236+
}
237+
}
238+
return f[0][n - 1];
239+
}
240+
};
241+
```
242+
243+
### **Go**
244+
245+
```go
246+
func mctFromLeafValues(arr []int) int {
247+
n := len(arr)
248+
f := make([][]int, n)
249+
g := make([][]int, n)
250+
for i := range g {
251+
f[i] = make([]int, n)
252+
g[i] = make([]int, n)
253+
g[i][i] = arr[i]
254+
for j := i + 1; j < n; j++ {
255+
g[i][j] = max(g[i][j-1], arr[j])
256+
}
257+
}
258+
var dfs func(int, int) int
259+
dfs = func(i, j int) int {
260+
if i == j {
261+
return 0
262+
}
263+
if f[i][j] > 0 {
264+
return f[i][j]
265+
}
266+
f[i][j] = 1 << 30
267+
for k := i; k < j; k++ {
268+
f[i][j] = min(f[i][j], dfs(i, k)+dfs(k+1, j)+g[i][k]*g[k+1][j])
269+
}
270+
return f[i][j]
271+
}
272+
return dfs(0, n-1)
273+
}
274+
275+
func max(a, b int) int {
276+
if a > b {
277+
return a
278+
}
279+
return b
280+
}
281+
282+
func min(a, b int) int {
283+
if a < b {
284+
return a
285+
}
286+
return b
287+
}
288+
```
289+
290+
```go
291+
func mctFromLeafValues(arr []int) int {
292+
n := len(arr)
293+
f := make([][]int, n)
294+
g := make([][]int, n)
295+
for i := range g {
296+
f[i] = make([]int, n)
297+
g[i] = make([]int, n)
298+
g[i][i] = arr[i]
299+
for j := i + 1; j < n; j++ {
300+
g[i][j] = max(g[i][j-1], arr[j])
301+
}
302+
}
303+
for i := n - 2; i >= 0; i-- {
304+
for j := i + 1; j < n; j++ {
305+
f[i][j] = 1 << 30
306+
for k := i; k < j; k++ {
307+
f[i][j] = min(f[i][j], f[i][k]+f[k+1][j]+g[i][k]*g[k+1][j])
308+
}
309+
}
310+
}
311+
return f[0][n-1]
312+
}
313+
314+
func max(a, b int) int {
315+
if a > b {
316+
return a
317+
}
318+
return b
319+
}
63320

321+
func min(a, b int) int {
322+
if a < b {
323+
return a
324+
}
325+
return b
326+
}
64327
```
65328

66329
### **...**

0 commit comments

Comments
 (0)