LeetCode 题解工作台
叶值的最小代价生成树
给你一个正整数数组 arr ,考虑所有满足以下条件的二叉树: 每个节点都有 0 个或是 2 个子节点。 数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。 每个非叶节点的值等于其左子树和右子树中叶节点的最大值的乘积。 在所有这样的二叉树中,返回每个非叶节点的值的最小可能总和。这个和的值是一…
5
题型
5
代码语言
3
相关题
当前训练重点
中等 · 状态·转移·动态规划
答案摘要
根据题目描述,数组 中的值与树的中序遍历中每个叶节点的值一一对应,我们可以将数组划分为左右两个非空子数组,分别对应树的左右子树,递归地求解每个子树的所有非叶节点的值的最小可能总和。 我们设计一个函数 $dfs(i, j)$,表示数组 中下标范围 $[i, j]$ 内的所有非叶节点的值的最小可能总和,那么答案就是 $dfs(0, n - 1)$,其中 为数组 的长度。
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路
题目描述
给你一个正整数数组 arr,考虑所有满足以下条件的二叉树:
- 每个节点都有
0个或是2个子节点。 - 数组
arr中的值与树的中序遍历中每个叶节点的值一一对应。 - 每个非叶节点的值等于其左子树和右子树中叶节点的最大值的乘积。
在所有这样的二叉树中,返回每个非叶节点的值的最小可能总和。这个和的值是一个 32 位整数。
如果一个节点有 0 个子节点,那么该节点为叶节点。
示例 1:
输入:arr = [6,2,4] 输出:32 解释:有两种可能的树,第一种的非叶节点的总和为 36 ,第二种非叶节点的总和为 32 。
示例 2:
输入:arr = [4,11] 输出:44
提示:
2 <= arr.length <= 401 <= arr[i] <= 15- 答案保证是一个 32 位带符号整数,即小于
231。
解题思路
方法一:记忆化搜索
根据题目描述,数组 中的值与树的中序遍历中每个叶节点的值一一对应,我们可以将数组划分为左右两个非空子数组,分别对应树的左右子树,递归地求解每个子树的所有非叶节点的值的最小可能总和。
我们设计一个函数 ,表示数组 中下标范围 内的所有非叶节点的值的最小可能总和,那么答案就是 ,其中 为数组 的长度。
函数 的计算过程如下:
- 如果 ,说明数组 中只有一个元素,没有非叶节点,因此 。
- 否则,我们枚举 ,将数组 划分为两个子数组 和 ,对于每个 ,我们递归计算 和 ,其中 表示数组 中下标范围 内的所有非叶节点的值的最小可能总和,而 表示数组 中下标范围 内的所有非叶节点的值的最小可能总和,那么 。
综上所述,我们可以得到:
上述递归过程中,我们可以使用记忆化搜索的方法,避免重复计算。另外,我们还可以使用数组 记录数组 中下标范围 内的所有叶节点的最大值,那么 的计算过程可以优化为:
最后,我们返回 即可。
时间复杂度 ,空间复杂度 。其中 为数组 的长度。
class Solution:
def mctFromLeafValues(self, arr: List[int]) -> int:
@cache
def dfs(i: int, j: int) -> Tuple:
if i == j:
return 0, arr[i]
s, mx = inf, -1
for k in range(i, j):
s1, mx1 = dfs(i, k)
s2, mx2 = dfs(k + 1, j)
t = s1 + s2 + mx1 * mx2
if s > t:
s = t
mx = max(mx1, mx2)
return s, mx
return dfs(0, len(arr) - 1)[0]
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | Depends on the final approach |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Do you consider overlapping subproblems for the subarray DP?
- question_mark
Can you reduce the O(n^3) DP with a greedy or stack-based method?
- question_mark
How do you maintain maximum leaf values efficiently during subarray merges?
常见陷阱
外企场景- error
Forgetting to correctly compute max(arr[i..k]) and max(arr[k+1..j]) in DP can inflate the sum.
- error
Incorrect stack handling can merge the wrong neighbors, giving a larger non-leaf sum.
- error
Not memoizing subarray results leads to TLE on larger arrays up to 40 elements.
进阶变体
外企场景- arrow_right_alt
Minimizing non-leaf sum when node value is the sum of maximum leaves instead of product.
- arrow_right_alt
Finding maximum non-leaf sum instead of minimum for the same leaf array.
- arrow_right_alt
Allowing leaves to appear multiple times, requiring adjusted DP state.