leetcode--二叉树中的最大路径和

news2024/11/13 12:43:07

leetcode地址:二叉树中的最大路径和
二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和 。

示例 1:
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/bbb8777d4de24c8e9c32da9cb9e1f00f.png

输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

示例 2:
在这里插入图片描述

输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

提示:

树中节点数目范围是 [1, 3 * 104]
-1000 <= Node.val <= 1000

实现思路

在二叉树中,路径被定义为一条节点序列,其中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中至多出现一次。路径至少包含一个节点,且不一定经过根节点。路径和是路径中各节点值的总和。给定一个二叉树的根节点,要求返回其最大路径和。

要找到最大路径和,我们需要考虑路径可以从任意节点开始和结束,并且路径可以不经过根节点。这意味着我们需要检查每个节点可能作为路径起点和终点的情况。

定义递归函数
我们定义一个递归函数 max_gain(node) 来计算节点的最大贡献值。这个函数计算从当前节点出发,延伸到左右子树所能获得的最大路径和。
计算当前节点的最大贡献值
如果当前节点为空,返回0。
计算左子树的最大贡献值,记为 left_gain。如果 left_gain 是负值,设置为0,因为负值不会增加路径和。
计算右子树的最大贡献值,记为 right_gain。如果 right_gain 是负值,设置为0,因为负值不会增加路径和。
计算路径和
计算当前节点作为路径最高点的路径和,即 node.val + left_gain + right_gain。
更新全局最大路径和。
返回节点的最大贡献值
返回节点的最大贡献值,即 node.val + max(left_gain, right_gain),因为路径只能选择一个子树继续延伸。

代码实现

# 定义二叉树节点类
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

# 最大路径和函数
def maxPathSum(root):
    def max_gain(node):
        nonlocal max_sum
        if not node:
            return 0
        
        # 递归计算左子树和右子树的最大贡献值
        left_gain = max(max_gain(node.left), 0)
        right_gain = max(max_gain(node.right), 0)
        
        # 当前节点的路径和
        current_path_sum = node.val + left_gain + right_gain
        
        # 更新最大路径和
        max_sum = max(max_sum, current_path_sum)
        
        # 返回节点的最大贡献值
        return node.val + max(left_gain, right_gain)
    
    max_sum = float('-inf')
    max_gain(root)
    return max_sum

# 测试示例
if __name__ == "__main__":
    # 创建测试二叉树
    #        -10
    #       /  \
    #      9   20
    #         /  \
    #        15   7
    root = TreeNode(-10)
    root.left = TreeNode(9)
    root.right = TreeNode(20)
    root.right.left = TreeNode(15)
    root.right.right = TreeNode(7)
    
    result = maxPathSum(root)
    print("最大路径和:", result)  # 应该输出42

go实现

package main

import (
	"fmt"
	"math"
)

// TreeNode 定义二叉树节点
type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

// maxPathSum 计算二叉树的最大路径和
func maxPathSum(root *TreeNode) int {
	maxSum := math.MinInt64

	var maxGain func(node *TreeNode) int
	maxGain = func(node *TreeNode) int {
		if node == nil {
			return 0
		}

		// 递归计算左子树和右子树的最大贡献值
		leftGain := max(maxGain(node.Left), 0)
		rightGain := max(maxGain(node.Right), 0)

		// 当前节点的路径和
		currentPathSum := node.Val + leftGain + rightGain

		// 更新最大路径和
		if currentPathSum > maxSum {
			maxSum = currentPathSum
		}

		// 返回节点的最大贡献值
		return node.Val + max(leftGain, rightGain)
	}

	maxGain(root)
	return maxSum
}

// 辅助函数,取两个整数中的最大值
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

// 测试示例
func main() {
	// 创建测试二叉树
	//        -10
	//       /  \
	//      9   20
	//         /  \
	//        15   7
	root := &TreeNode{Val: -10}
	root.Left = &TreeNode{Val: 9}
	root.Right = &TreeNode{Val: 20}
	root.Right.Left = &TreeNode{Val: 15}
	root.Right.Right = &TreeNode{Val: 7}

	result := maxPathSum(root)
	fmt.Printf("最大路径和: %d\n", result) // 应该输出42
}

kotlin实现

// 定义二叉树节点类
class TreeNode(var `val`: Int) {
    var left: TreeNode? = null
    var right: TreeNode? = null
}

// 最大路径和函数
fun maxPathSum(root: TreeNode?): Int {
    var maxSum = Int.MIN_VALUE

    fun maxGain(node: TreeNode?): Int {
        if (node == null) return 0

        // 递归计算左子树和右子树的最大贡献值
        val leftGain = maxOf(maxGain(node.left), 0)
        val rightGain = maxOf(maxGain(node.right), 0)

        // 当前节点的路径和
        val currentPathSum = node.`val` + leftGain + rightGain

        // 更新最大路径和
        maxSum = maxOf(maxSum, currentPathSum)

        // 返回节点的最大贡献值
        return node.`val` + maxOf(leftGain, rightGain)
    }

    maxGain(root)
    return maxSum
}

// 测试示例
fun main() {
    // 创建测试二叉树
    //        -10
    //       /  \
    //      9   20
    //         /  \
    //        15   7
    val root = TreeNode(-10).apply {
        left = TreeNode(9)
        right = TreeNode(20).apply {
            left = TreeNode(15)
            right = TreeNode(7)
        }
    }

    val result = maxPathSum(root)
    println("最大路径和: $result")  // 应该输出42
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1925789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编译x-Wrt 全过程

参考自;​​​​​​c编译教程 | All about X-Wrt 需要详细了解的小伙伴还请参看原文 ^-^ 概念&#xff1a; x-wrt&#xff08;基于openwrt深度定制的发行版本&#xff09; 编译系统: ubuntu22.04 注意&#xff1a; 特别注意的是&#xff0c;整个编译过程&#xff0c;都是用 …

C到C嘎嘎的衔接篇

本篇文章&#xff0c;是帮助大家从C向C嘎嘎的过渡&#xff0c;那么我们直接开始吧 不知道大家是否有这样一个问题&#xff0c;学完C的时候感觉还能听懂&#xff0c;但是听C嘎嘎感觉就有点难度或者说很难听懂&#xff0c;那么本篇文章就是帮助大家从C过渡到C嘎嘎。 C嘎嘎与C的区…

代码随想录算法训练营第三十四天|322. 零钱兑换、279.完全平方数

322. 零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1。 dp[j]凑足总额为j的方法有dp[j]个。 递推公式&#xff1a;凑足金额为j-coins[i]的方法有d…

linux下安装cutecom串口助手;centos安装cutecom串口助手;rpm安装包安装cutecom串口助手

在支持apt-get的系统下安装 在终端命令行中输入&#xff1a; sudo apt-get install cutecom 安装好后输入 sudo cutecom 就可以了 关于如何使用&#xff0c;可以看这个https://www.cnblogs.com/xingboy/p/14388610.html 如果你的电脑不支持apt-get。 那我们就通过安装包…

【Android】kotlin jdk版本冲突与Kotlin依赖管理插件

1、androidx.activity&#xff1a;activity&#xff1a;1.8.0 依赖版本错误问题 *依赖项“androidx.activity&#xff1a;activity&#xff1a;1.8.0”要求依赖它的库和应用针对版本 34 或更高版本 Android API 进行编译。&#xff1a;app 目前是针对 android-33 编译的。此外…

QTabWidget、QListWidget、QStackedWidget

The QTabWidget class provides a stack of tabbed widgets. More... The QListWidget class provides an item-based list widget. More... QStringList strlist;strlist<<"系统"<<"外观"<<"截图"<<"贴图"…

FPGA设计之跨时钟域(CDC)设计篇(1)----亚稳态到底是什么?

1、什么是亚稳态? 在数字电路中,如果数据传输时不满足触发器FF的建立时间要求Tsu和保持时间要求Th,就可能产生亚稳态(Metastability),此时触发器的输出端(Q端)在有效时钟沿之后比较长的一段时间都会处于不确定的状态(在0和1之间振荡),而不是等于数据输入端(D端)的…

Java NIO 总结: NIO技术基础回顾

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

k8s集群新增节点

目前集群状态 如K8S 集群搭建中规划的集群一样 Masternode01node02IP192.168.100.100192.168.100.101192.168.100.102OSCent OS 7.9Cent OS 7.9Cent OS 7.9 目前打算新增节点node03 Masternode01node02node03IP192.168.100.100192.168.100.101192.168.100.102192.168.100.1…

Java核心篇之JVM探秘:对象创建与内存分配机制

系列文章目录 第一章 Java核心篇之JVM探秘&#xff1a;内存模型与管理初探 第二章 Java核心篇之JVM探秘&#xff1a;对象创建与内存分配机制 第三章 Java核心篇之JVM探秘&#xff1a;垃圾回收算法与垃圾收集器 第四章 Java核心篇之JVM调优实战&#xff1a;Arthas工具使用及…

Windows11终端winget配置

一、工具安装 Windows11是自带该工具的&#xff0c;如果wind10&#xff0c;可以找应用商店和GitHub上进行下载。 安装地址使用 winget 工具安装和管理应用程序 | Microsoft Learn 发布地址 Releases microsoft/terminal GitHub 二、无法使用问题排错 在命令行界面出现以…

鸿蒙读取本地文件同步,异步的优化问题

一、问题引入 有这样一个业务场景&#xff0c; 在进入一个新页面前&#xff0c;需要读取本地文件 。 当这个文件比较大时 &#xff0c;会造成加载页面时间过长。 二、 问题讲解 一般在页面的aboutToAppear里&#xff0c;我们会同步读取文件 &#xff0c; 因为页面UI 依赖文件…

sql monitoring 长SQL ASH AWR 都没有 未Commit or export to csv

Duration 4小时&#xff0c; Database Time 22.5&#xff0c; Session Inactive&#xff0c; 1.未Commit原因, 2.慢慢导出成csv文件&#xff1f; How is v$session status INACTIVE and v$sql_monitor status EXECUTING concurrently 2641811 Posts: 8 Jan 11, 2016 6:47P…

【Linux】重定向 | 为什么说”一切皆文件?“

目录 前言 1.文件描述符分配规则 2.dup2 重定向接口 3.重定向 3.1>输出重定向 3.2>>追加重定向 3.3<输入重定向 3.4 shell 模拟实现< > 3.5 理解> 4. 理解“Linux 下一切皆文件” 前言 问&#xff1a;fd 为什么默认从 3 开始&#xff0c;而不是…

手机怎么用代理ip上网

在数字化时代&#xff0c;网络已经成为我们生活中不可或缺的一部分。然而&#xff0c;有时候出于安全、隐私或访问特定网络资源的需要&#xff0c;我们可能需要使用代理IP来上网。那么&#xff0c;什么是代理IP&#xff1f;如何在手机上设置并使用它呢&#xff1f;本文将为您详…

聚观早报 | 网宿科技推出边缘AI网关;AMD再收购AI公司

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 7月12日消息 网宿科技推出边缘AI网关 AMD再收购AI公司 谷歌Pixel 9系列将配超声波指纹 三星Galaxy Z Fold6亮相 …

如何写论文的讨论和结论部分,提升审稿通过率300%?(附例句模版)

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 关于论文讨论Discussion部分的撰写&#xff0c;娜姐之前写过几篇文章&#xff1a; 1 Discussion讨论部分被3个审稿人说没深度没逻辑&#xff0c;用这个AI工具三步拯救了我&am…

前端插槽简易版详解【适合有点基础但是有点迷糊的同学查阅】

简易版默认插槽 默认插槽也有自己的名字 效果&#xff1a; 具名插槽 简写 萝卜坑可以种组件哦 插槽传值&#xff1a;父组件用scope接收---变成一个对象

udp协议模拟远程输入指令控制xshell

不了解udp协议的可以先看一下udp协议下的socket函数_udp socket函数-CSDN博客 我之前还写过模拟实现xshell的模拟实现简单的shell-CSDN博客 如今我们要模拟的是让别人连网络连到我们主机&#xff0c;他可以执行命令&#xff1a; 1.接口 我们之前是用execl系列的函数来实现的…

【Android】Service介绍和生命周期

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 介绍 Service是Android程序中四大基础组件之一&#xff0c;它和Activity一样都是Context的子类&#xff0c;只不…