在Go(Golang)中找出二叉树最大路径总和的程序

250 阅读1分钟

概述

给出一棵二叉树。目标是找到该二叉树中的最大路径总和。 二叉树中的路径是一个相互连接的节点序列。每个节点在最大路径总和中只出现一次。

例子1

Output: 16
Maximum Sum Path is: 4->2->1->3->6

例2

Output: 14
Maximum Sum Path is: 5->3->6

我们的想法是在每个节点上跟踪以下四个值

  • a = root.Val

  • b = root.Val + leftSubTreeMaxSum

  • c = root.Val + rightSubTreeMaxSum

  • d = root.Val + leftSubTreeMaxSum+ rightSubTreeMaxSum

然后

  • 给定节点的最大和是 (a,b,c,d) 的最大值。

  • 递归调用的返回值将是 (a,b,c) 的最大值。 为什么呢?这是因为只有a或b或c的路径代表了在父节点上可以被考虑的路径。为了用一个例子来理解这一点,请考虑上面例子二中的二叉树。路径5->3->6不能将父节点 -5 纳入其路径中,因为它成为无效路径。

程序

下面是同样的程序

package main

import (
	"fmt"
	"math"
)

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

func maxPathSum(root *TreeNode) int {
	res := math.MinInt64

	maxPathSumUtil(root, &res)
	return res
}

func maxPathSumUtil(root *TreeNode, res *int) int {
	if root == nil {
		return 0
	}

	l := maxPathSumUtil(root.Left, res)
	r := maxPathSumUtil(root.Right, res)

	a := root.Val
	b := root.Val + l
	c := root.Val + r
	d := root.Val + l + r

	maxReturnSum := maxOfThree(a, b, c)

	maxSumPath := maxOfTwo(maxReturnSum, d)
	if maxSumPath > *res {
		*res = maxSumPath
	}

	return maxReturnSum
}

func maxOfThree(a, b, c int) int {
	if a > b && a > c {
		return a
	}

	if b > c {
		return b
	}

	return c
}

func maxOfTwo(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	root := &TreeNode{Val: 1}
	root.Left = &TreeNode{Val: 2}
	root.Left.Left = &TreeNode{Val: 4}
	root.Right = &TreeNode{Val: 3}
	root.Right.Left = &TreeNode{Val: 5}
	root.Right.Right = &TreeNode{Val: 6}

	output := maxPathSum(root)
	fmt.Println(output)

	root = &TreeNode{Val: -10}
	root.Left = &TreeNode{Val: 2}
	root.Left.Left = &TreeNode{Val: 4}
	root.Right = &TreeNode{Val: 3}
	root.Right.Left = &TreeNode{Val: 5}
	root.Right.Right = &TreeNode{Val: 6}
	output = maxPathSum(root)
	fmt.Println(output)

}

输出:

16
14