2021-02-26:一个数组arr是二叉树的中序遍历结果,每条边的开销是父节点和子节点的乘积,总开销是所有边的开销之和。请问最

举报
福大大架构师每日一题 发表于 2021/02/26 22:29:40 2021/02/26
【摘要】 2021-02-26:一个数组arr是二叉树的中序遍历结果,每条边的开销是父节点和子节点的乘积,总开销是所有边的开销之和。请问最小总开销是多少?链接:https://www.nowcoder.com/questionTerminal/0d939e874a004f449a370aca1346dd5c来源:牛客网小团有一个由N个节点组成的二叉树,每个节点有一个权值。定义二叉树每条边的开销为其两端...

2021-02-26:一个数组arr是二叉树的中序遍历结果,每条边的开销是父节点和子节点的乘积,总开销是所有边的开销之和。请问最小总开销是多少?

链接:https://www.nowcoder.com/questionTerminal/0d939e874a004f449a370aca1346dd5c
来源:牛客网

小团有一个由N个节点组成的二叉树,每个节点有一个权值。定义二叉树每条边的开销为其两端节点权值的乘积,二叉树的总开销即每条边的开销之和。小团按照二叉树的中序遍历依次记录下每个节点的权值,即他记录下了N个数,第i个数表示位于中序遍历第i个位置的节点的权值。之后由于某种原因,小团遗忘了二叉树的具体结构。在所有可能的二叉树中,总开销最小的二叉树被称为最优二叉树。现在,小团请小美求出最优二叉树的总开销。

输入描述:
第一行输入一个整数N(1<=N<=300),表示二叉树的节点数。
第二行输入N个由空格隔开的整数,表示按中序遍历记录下的各个节点的权值,所有权值均为不超过1000的正整数。

输出描述:
输出一个整数,表示最优二叉树的总开销。

福哥答案2021-02-26:

自然智慧即可。
1.递归。有代码。
2.记忆化搜索。有代码。

代码用golang编写,代码如下:

```go
package main

import "fmt"

const MAX = int(^uint(0) >> 1)

//https://www.nowcoder.com/questionTerminal/0d939e874a004f449a370aca1346dd5c
func main() {
    arr := []int{7, 6, 5, 1, 3}
    ret := f1(arr)
    fmt.Println("1.递归:", ret)

    ret = f2(arr)
    fmt.Println("2.记忆化搜索:", ret)
}

func f1(arr []int) int {
    arrLen := len(arr)
    if arrLen <= 1 {
        return 0
    }
    return process1(arr, -1, 0, arrLen-1)
}

func process1(arr []int, cur int, L int, R int) int {
    length := R - L + 1
    if length == 0 {
        return 0
    }
    ans := MAX
    for i := L; i <= R; i++ {
        temp := 0
        if cur >= 0 {
            temp = arr[cur] * arr[i]
        }
        ans = getMin(temp+process1(arr, i, L, i-1)+process1(arr, i, i+1, R), ans)
    }
    return ans

}

func f2(arr []int) int {
    arrLen := len(arr)
    if arrLen <= 1 {
        return 0
    }
    dp := make([][][]int, arrLen+1)
    for i := 0; i < arrLen+1; i++ {
        dp[i] = make([][]int, arrLen)
        for j := 0; j < arrLen; j++ {
            dp[i][j] = make([]int, arrLen)
            for k := 0; k < arrLen; k++ {
                dp[i][j][k] = -1
            }
        }
    }

    ret := process2(arr, -1, 0, arrLen-1, dp)
    //fmt.Println(dp)
    return ret
}

func process2(arr []int, cur int, L int, R int, dp [][][]int) int {
    length := R - L + 1
    if length == 0 {
        return 0
    }
    if dp[cur+1][L][R] != -1 {
        //fmt.Println("记忆化", dp[cur+1][L][R])
        return dp[cur+1][L][R]
    }
    ans := MAX
    for i := L; i <= R; i++ {
        temp := 0
        if cur >= 0 {
            temp = arr[cur] * arr[i]
        }
        ans = getMin(temp+process2(arr, i, L, i-1, dp)+process2(arr, i, i+1, R, dp), ans)
    }
    dp[cur+1][L][R] = ans
    return ans

}
func getMin(a int, b int) int {
    if a < b {
        return a
    } else {
        return b
    }
}
```
执行结果如下:

***
[评论](https://user.qzone.qq.com/3182319461/blog/1614294157)

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。