使用kotlin解决这个问题:1130. 叶值的最小代价生成树 提示 中等 311 相关企业 给你一个正整数数组 arr,考虑所有满足以下条件的二叉树: 每个节点都有 0 个或是 2 个子节点。 数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。 每个非叶节点的值等于其左子树和右子树中叶节点的最大值的乘积。 在所有这样的二叉树中,返回每个非叶节点的值的最小可能总和。这个和的值是一个 32 位整数。 如果一个节点有 0 个子节点,那么该节点为叶节点。 示例 1: 输入:arr = [6,2,4] 输出:32 解释:有两种可能的树,第一种的非叶节点的总和为 36 ,第二种非叶节点的总和为 32 。 示例 2: 输入:arr = [4,11] 输出:44
时间: 2024-01-08 22:10:03 浏览: 27
下面是使用 Kotlin 解决这个问题的代码,其中用到了动态规划的思想:
```kotlin
fun mctFromLeafValues(arr: IntArray): Int {
val n = arr.size
val dp = Array(n) { IntArray(n) { Int.MAX_VALUE } }
for (i in 0 until n) {
dp[i][i] = arr[i]
}
for (len in 2..n) {
for (i in 0..n - len) {
val j = i + len - 1
for (k in i until j) {
val leftMax = dp[i][k]
val rightMax = dp[k + 1][j]
val rootVal = getMaxLeafValue(arr, i, k) * getMaxLeafValue(arr, k + 1, j)
dp[i][j] = minOf(dp[i][j], leftMax + rightMax + rootVal)
}
}
}
return dp[0][n - 1]
}
private fun getMaxLeafValue(arr: IntArray, left: Int, right: Int): Int {
var maxVal = arr[left]
for (i in left + 1..right) {
maxVal = maxOf(maxVal, arr[i])
}
return maxVal
}
```
这里定义了一个 `dp` 数组,其中 `dp[i][j]` 表示从第 `i` 个叶节点到第 `j` 个叶节点的最小可能总和。初始状态下,`dp[i][i]` 即为叶节点本身的值。
然后,我们使用动态规划的思想,从小到大枚举区间长度 `len`,以及区间左右端点 `i` 和 `j`。对于每个区间,我们枚举其分割点 `k`,计算左右子树的最大叶节点值,然后根据题目要求计算出根节点的值,并更新 `dp[i][j]`。
最终得到的 `dp[0][n-1]` 即为整棵树的最小可能总和。