Skip to content

Commit 2c6a24e

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

File tree

7 files changed

+238
-119
lines changed

7 files changed

+238
-119
lines changed

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

Lines changed: 104 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,25 @@
5151

5252
**方法一:记忆化搜索**
5353

54-
根据题目描述,数组 $arr$ 中的值与树的中序遍历中每个叶节点的值一一对应,因此可以将数组 $arr$ 中的值看作是树的叶节点,我们可以将数组划分为左右两个子数组,分别对应树的左右子树,递归地每个子树的所有非叶子节点的值的最小可能总和
54+
根据题目描述,数组 $arr$ 中的值与树的中序遍历中每个叶节点的值一一对应,我们可以将数组划分为左右两个非空子数组,分别对应树的左右子树,递归地求解每个子树的所有非叶节点的值的最小可能总和
5555

56-
我们设计一个函数 $dfs(i, j)$,表示数组 $arr$ 中下标范围 $[i, j]$ 内的所有叶节点的值的最小可能总和,那么答案就是 $dfs(0, n - 1)$,其中 $n$ 为数组 $arr$ 的长度。
56+
我们设计一个函数 $dfs(i, j)$,表示数组 $arr$ 中下标范围 $[i, j]$ 内的所有非叶节点的值的最小可能总和,那么答案就是 $dfs(0, n - 1)$,其中 $n$ 为数组 $arr$ 的长度。
5757

5858
函数 $dfs(i, j)$ 的计算过程如下:
5959

60-
- 如果 $i = j$,说明数组 $arr$ 中只有一个元素,因此 $dfs(i, j) = 0$。
61-
- 否则,我们枚举 $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]\}\}$。
60+
- 如果 $i = j$,说明数组 $arr[i..j]$ 中只有一个元素,因此 $dfs(i, j) = 0$。
61+
- 否则,我们枚举 $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]\}\}$。
6262

63-
上述递归过程中,我们可以使用记忆化搜索的方法进行优化,避免重复计算。
63+
综上所述,我们可以得到:
64+
65+
$$
66+
dfs(i, j) = \begin{cases}
67+
0, & \text{if } i = j \\
68+
\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]\}\}, & \text{if } i < j
69+
\end{cases}
70+
$$
71+
72+
上述递归过程中,我们可以使用记忆化搜索的方法,避免重复计算。
6473

6574
最后,我们返回 $dfs(0, n - 1)$ 即可。
6675

@@ -70,7 +79,14 @@
7079

7180
我们可以将方法一中的记忆化搜索改为动态规划的方式进行求解。
7281

73-
定义 $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]\}$。
82+
定义 $f[i][j]$ 表示数组 $arr$ 中下标范围 $[i, j]$ 内的所有非叶节点的值的最小可能总和,而 $g[i][j]$ 表示数组 $arr$ 中下标范围 $[i, j]$ 内的所有叶节点的最大值,那么状态转移方程为:
83+
84+
$$
85+
f[i][j] = \begin{cases}
86+
0, & \text{if } i = j \\
87+
\min_{i \leq k < j} \{f[i][k] + f[k + 1][j] + g[i][k] \cdot g[k + 1][j]\}, & \text{if } i < j
88+
\end{cases}
89+
$$
7490

7591
最后,我们返回 $f[0][n - 1]$ 即可。
7692

@@ -86,7 +102,7 @@
86102
class Solution:
87103
def mctFromLeafValues(self, arr: List[int]) -> int:
88104
@cache
89-
def dfs(i: int, j: int):
105+
def dfs(i: int, j: int) -> Tuple:
90106
if i == j:
91107
return 0, arr[i]
92108
s, mx = inf, -1
@@ -105,18 +121,32 @@ class Solution:
105121
```python
106122
class Solution:
107123
def mctFromLeafValues(self, arr: List[int]) -> int:
124+
@cache
125+
def dfs(i: int, j: int) -> int:
126+
if i == j:
127+
return 0
128+
return min(dfs(i, k) + dfs(k + 1, j) + g[i][k] * g[k + 1][j] for k in range(i, j))
129+
108130
n = len(arr)
109-
f = [[0] * n for _ in range(n)]
110131
g = [[0] * n for _ in range(n)]
111-
for i in range(n):
132+
for i in range(n - 1, -1, -1):
112133
g[i][i] = arr[i]
113134
for j in range(i + 1, n):
114135
g[i][j] = max(g[i][j - 1], arr[j])
136+
return dfs(0, n - 1)
137+
```
138+
139+
```python
140+
class Solution:
141+
def mctFromLeafValues(self, arr: List[int]) -> int:
142+
n = len(arr)
143+
f = [[0] * n for _ in range(n)]
144+
g = [[0] * n for _ in range(n)]
115145
for i in range(n - 1, -1, -1):
146+
g[i][i] = arr[i]
116147
for j in range(i + 1, n):
117-
f[i][j] = inf
118-
for k in range(i, j):
119-
f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + g[i][k] * g[k + 1][j])
148+
g[i][j] = max(g[i][j - 1], arr[j])
149+
f[i][j] = min(f[i][k] + f[k + 1][j] + g[i][k] * g[k + 1][j] for k in range(i, j))
120150
return f[0][n - 1]
121151
```
122152

@@ -133,9 +163,9 @@ class Solution {
133163
int n = arr.length;
134164
f = new Integer[n][n];
135165
g = new int[n][n];
136-
for (int i = 0; i < n; i++) {
166+
for (int i = n - 1; i >= 0; --i) {
137167
g[i][i] = arr[i];
138-
for (int j = i + 1; j < n; j++) {
168+
for (int j = i + 1; j < n; ++j) {
139169
g[i][j] = Math.max(g[i][j - 1], arr[j]);
140170
}
141171
}
@@ -164,14 +194,10 @@ class Solution {
164194
int n = arr.length;
165195
int[][] f = new int[n][n];
166196
int[][] g = new int[n][n];
167-
for (int i = 0; i < n; ++i) {
197+
for (int i = n - 1; i >= 0; --i) {
168198
g[i][i] = arr[i];
169199
for (int j = i + 1; j < n; ++j) {
170200
g[i][j] = Math.max(g[i][j - 1], arr[j]);
171-
}
172-
}
173-
for (int i = n - 2; i >= 0; --i) {
174-
for (int j = i + 1; j < n; ++j) {
175201
f[i][j] = 1 << 30;
176202
for (int k = i; k < j; ++k) {
177203
f[i][j] = Math.min(f[i][j], f[i][k] + f[k + 1][j] + g[i][k] * g[k + 1][j]);
@@ -193,7 +219,7 @@ public:
193219
int f[n][n];
194220
int g[n][n];
195221
memset(f, 0, sizeof(f));
196-
for (int i = 0; i < n; ++i) {
222+
for (int i = n - 1; ~i; --i) {
197223
g[i][i] = arr[i];
198224
for (int j = i + 1; j < n; ++j) {
199225
g[i][j] = max(g[i][j - 1], arr[j]);
@@ -225,14 +251,10 @@ public:
225251
int f[n][n];
226252
int g[n][n];
227253
memset(f, 0, sizeof(f));
228-
for (int i = 0; i < n; ++i) {
254+
for (int i = n - 1; ~i; --i) {
229255
g[i][i] = arr[i];
230256
for (int j = i + 1; j < n; ++j) {
231257
g[i][j] = max(g[i][j - 1], arr[j]);
232-
}
233-
}
234-
for (int i = n - 2; ~i; --i) {
235-
for (int j = i + 1; j < n; ++j) {
236258
f[i][j] = 1 << 30;
237259
for (int k = i; k < j; ++k) {
238260
f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + g[i][k] * g[k + 1][j]);
@@ -299,13 +321,11 @@ func mctFromLeafValues(arr []int) int {
299321
for i := range g {
300322
f[i] = make([]int, n)
301323
g[i] = make([]int, n)
324+
}
325+
for i := n - 1; i >= 0; i-- {
302326
g[i][i] = arr[i]
303327
for j := i + 1; j < n; j++ {
304328
g[i][j] = max(g[i][j-1], arr[j])
305-
}
306-
}
307-
for i := n - 2; i >= 0; i-- {
308-
for j := i + 1; j < n; j++ {
309329
f[i][j] = 1 << 30
310330
for k := i; k < j; k++ {
311331
f[i][j] = min(f[i][j], f[i][k]+f[k+1][j]+g[i][k]*g[k+1][j])
@@ -330,6 +350,61 @@ func min(a, b int) int {
330350
}
331351
```
332352

353+
### **TypeScript**
354+
355+
```ts
356+
function mctFromLeafValues(arr: number[]): number {
357+
const n = arr.length;
358+
const f: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
359+
const g: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
360+
for (let i = n - 1; i >= 0; --i) {
361+
g[i][i] = arr[i];
362+
for (let j = i + 1; j < n; ++j) {
363+
g[i][j] = Math.max(g[i][j - 1], arr[j]);
364+
}
365+
}
366+
const dfs = (i: number, j: number): number => {
367+
if (i === j) {
368+
return 0;
369+
}
370+
if (f[i][j] > 0) {
371+
return f[i][j];
372+
}
373+
let ans = 1 << 30;
374+
for (let k = i; k < j; ++k) {
375+
ans = Math.min(
376+
ans,
377+
dfs(i, k) + dfs(k + 1, j) + g[i][k] * g[k + 1][j],
378+
);
379+
}
380+
return (f[i][j] = ans);
381+
};
382+
return dfs(0, n - 1);
383+
}
384+
```
385+
386+
```ts
387+
function mctFromLeafValues(arr: number[]): number {
388+
const n = arr.length;
389+
const f: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
390+
const g: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
391+
for (let i = n - 1; i >= 0; --i) {
392+
g[i][i] = arr[i];
393+
for (let j = i + 1; j < n; ++j) {
394+
g[i][j] = Math.max(g[i][j - 1], arr[j]);
395+
f[i][j] = 1 << 30;
396+
for (let k = i; k < j; ++k) {
397+
f[i][j] = Math.min(
398+
f[i][j],
399+
f[i][k] + f[k + 1][j] + g[i][k] * g[k + 1][j],
400+
);
401+
}
402+
}
403+
}
404+
return f[0][n - 1];
405+
}
406+
```
407+
333408
### **...**
334409

335410
```

0 commit comments

Comments
 (0)