leetcode--二叉树中的最长交错路径

leetcode地址:二叉树中的最长交错路径
给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下:

选择二叉树中 任意 节点和一个方向(左或者右)。
如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。
改变前进方向:左变右或者右变左。
重复第二步和第三步,直到你在树中无法继续移动。
交错路径的长度定义为:访问过的节点数目 - 1(单个节点的路径长度为 0 )。

请你返回给定树中最长 交错路径 的长度。

示例 1:

在这里插入图片描述

输入:root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1,null,1]
输出:3
解释:蓝色节点为树中最长交错路径(右 -> 左 -> 右)。
示例 2:

在这里插入图片描述

输入:root = [1,1,1,null,1,null,null,1,1,null,1]
输出:4
解释:蓝色节点为树中最长交错路径(左 -> 右 -> 左 -> 右)。
示例 3:

输入:root = [1]
输出:0

提示:

每棵树最多有 50000 个节点。
每个节点的值在 [1, 100] 之间。

实现思路

实现最长交错路径(Longest ZigZag Path)的问题涉及在二叉树中找到一条路径,该路径上的每一步都在左右子树之间交替。具体来说,路径从根节点开始,每次选择左子节点或右子节点,但不能连续两次选择同一个方向。最长交错路径的长度是这条路径上边的数量。

代码详解

  1. 定义数据结构
    首先,定义一个二叉树节点的类,用于表示树中的每个节点。
class TreeNode:
    def __init__(self, value=0, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right
  1. 初始化类和变量
    在解决方案类中,定义一个变量来记录最长交错路径的长度,并初始化该类。
class Solution:
    def __init__(self):
        self.max_length = 0
  1. 定义递归函数
    使用深度优先搜索(DFS)来遍历二叉树。在每个节点,记录当前路径的长度,并更新最长交错路径的长度。定义递归函数 dfs 来处理这个过程。
def dfs(node, direction, length):
    if not node:
        return
    self.max_length = max(self.max_length, length)
    if direction == 'left':
        dfs(node.left, 'left', 1)  # 重置左边路径长度
        dfs(node.right, 'right', length + 1)  # 继续增加右边路径长度
    else:
        dfs(node.left, 'left', length + 1)  # 继续增加左边路径长度
        dfs(node.right, 'right', 1)  # 重置右边路径长度
  1. 调用递归函数
    在主函数 longestZigZag 中,从根节点开始,以左和右两个方向调用递归函数 dfs。
def longestZigZag(self, root: TreeNode) -> int:
    dfs(root, 'left', 0)
    dfs(root, 'right', 0)
    return self.max_length
  1. 将上述步骤组合成完整的代码:
class TreeNode:
    def __init__(self, value=0, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right

class Solution:
    def __init__(self):
        self.max_length = 0

    def longestZigZag(self, root: TreeNode) -> int:
        def dfs(node, direction, length):
            if not node:
                return
            self.max_length = max(self.max_length, length)
            if direction == 'left':
                dfs(node.left, 'left', 1)  # 重置左边路径长度
                dfs(node.right, 'right', length + 1)  # 继续增加右边路径长度
            else:
                dfs(node.left, 'left', length + 1)  # 继续增加左边路径长度
                dfs(node.right, 'right', 1)  # 重置右边路径长度

        dfs(root, 'left', 0)
        dfs(root, 'right', 0)
        return self.max_length

# 示例二叉树
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.right = TreeNode(4)
root.left.right.left = TreeNode(5)
root.left.right.right = TreeNode(6)

# 计算最长交错路径
solution = Solution()
result = solution.longestZigZag(root)
print("最长交错路径长度:", result)

关键点总结
二叉树节点类:用于表示树的结构。
深度优先搜索(DFS):用于遍历二叉树。
递归:在每个节点记录路径的长度,并更新最长交错路径的长度。
方向标志:用 direction 参数来指示当前路径的方向(左或右),并在递归调用时进行交替。
路径长度记录:用 length 参数来记录当前路径的长度,并更新 self.max_length 以记录最长路径的长度。
通过这些步骤,可以有效地计算出二叉树中最长的交错路径。

GO语言实现

package main

import "fmt"

// TreeNode 表示二叉树的节点
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// Solution 结构体用于记录最长交错路径的长度
type Solution struct {
    maxLength int
}

// NewSolution 初始化 Solution
func NewSolution() *Solution {
    return &Solution{maxLength: 0}
}

// dfs 递归函数遍历二叉树
func (s *Solution) dfs(node *TreeNode, direction string, length int) {
    if node == nil {
        return
    }

    // 更新最长路径长度
    if length > s.maxLength {
        s.maxLength = length
    }

    if direction == "left" {
        s.dfs(node.Left, "left", 1)         // 重置左边路径长度
        s.dfs(node.Right, "right", length+1) // 继续增加右边路径长度
    } else {
        s.dfs(node.Left, "left", length+1)  // 继续增加左边路径长度
        s.dfs(node.Right, "right", 1)       // 重置右边路径长度
    }
}

// LongestZigZag 计算二叉树的最长交错路径
func (s *Solution) LongestZigZag(root *TreeNode) int {
    s.dfs(root, "left", 0)
    s.dfs(root, "right", 0)
    return s.maxLength
}

func main() {
    // 构建示例二叉树
    root := &TreeNode{Val: 1}
    root.Left = &TreeNode{Val: 2}
    root.Right = &TreeNode{Val: 3}
    root.Left.Right = &TreeNode{Val: 4}
    root.Left.Right.Left = &TreeNode{Val: 5}
    root.Left.Right.Right = &TreeNode{Val: 6}

    // 计算最长交错路径
    solution := NewSolution()
    result := solution.LongestZigZag(root)
    fmt.Println("最长交错路径长度:", result)
}

kotlin实现

class TreeNode(val value: Int) {
    var left: TreeNode? = null
    var right: TreeNode? = null
}

class Solution {
    private var maxLength = 0

    private fun dfs(node: TreeNode?, direction: String, length: Int) {
        if (node == null) return

        // 更新最长路径长度
        if (length > maxLength) {
            maxLength = length
        }

        if (direction == "left") {
            dfs(node.left, "left", 1)       // 重置左边路径长度
            dfs(node.right, "right", length + 1) // 继续增加右边路径长度
        } else {
            dfs(node.left, "left", length + 1)  // 继续增加左边路径长度
            dfs(node.right, "right", 1)     // 重置右边路径长度
        }
    }

    fun longestZigZag(root: TreeNode?): Int {
        dfs(root, "left", 0)
        dfs(root, "right", 0)
        return maxLength
    }
}

fun main() {
    // 构建示例二叉树
    val root = TreeNode(1)
    root.left = TreeNode(2)
    root.right = TreeNode(3)
    root.left?.right = TreeNode(4)
    root.left?.right?.left = TreeNode(5)
    root.left?.right?.right = TreeNode(6)

    // 计算最长交错路径
    val solution = Solution()
    val result = solution.longestZigZag(root)
    println("最长交错路径长度: $result")
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《vue3》reactivity API(vue3的$set呢?)

在Vue2中&#xff0c;修改某一些数据&#xff0c;视图是不能及时重新渲染的。 比如数组 <div> {{ myHobbies }} </div>data: () > ({myHobbies: [篮球, 羽毛球, 桌球] }); mounted () {this.myHobbies[1] sing; // 视图层并没有改变 }因此&#xff0c;Vue2就提…

实验2 字符及字符串输入输出与分支程序设计实验

字符及字符串输入输出 从键盘输入两个一位十进制数&#xff0c;计算这两个数之和&#xff0c;并将结果在屏幕上显示出来。 分支程序设计 从键盘输入一字符&#xff0c;判断该字符是小写字母、大写字母、数字或者其他字符。若输入为小写字母&#xff0c;显示“You Input a Lo…

无忧易售功能:刊登页面文本翻译,无缝对接全球买家

每一个词语&#xff0c;每一句话&#xff0c;都承载着产品的灵魂和品牌的故事&#xff0c;无忧易售的刊登页面文本翻译服务&#xff0c;一键操作即可将你的产品介绍、详情或广告文案转化为多语言版本&#xff0c;轻松管理&#xff0c;高效发布。 一、Allegro、OZON、Coupang、…

手动将dingtalk-sdk-java jar包打入maven本地仓库

有时候,中央镜像库不一定有自己需要的jar包,这时候我们就需要用到该方法,将jar打入maven本地仓库,然后项目中,正常使用maven的引入规则。 mvn install:install-file -Dmaven.repo.local=D:\software\maven\apache-maven-3.6.3-bin\apache-maven-3.6.3\repo -DgroupId=ding…

高德地图轨迹回放并提示具体信息

先上效果图 到达某地点后显示提示语&#xff1a;比如&#xff1a;12&#xff1a;56分驶入康庄大道、左转驶入xx大道等 <!doctype html> <html> <head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"…

Datawhale AI夏令营2024 Task3

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 #AI夏令营 #Datawhale #夏令营 一、数据集制作1.1 环境配置1.2 数据处理prompt1.3 训练数据集制作1.4 测试集数据制作 二、模型微调2.1 平台微调2.2 平台微调 三、微调推理提…

天环公益原创开发进度网站源码带后台免费分享

天环公益计划首发原创开发进度网站源码带后台免费分享 后台地址是&#xff1a;admin.php 后台没有账号密码 这个没有数据库 有能力的可以自己改 天环公益原创开发进度网站 带后台

【Vue】使用html、css实现鱼骨组件

文章目录 组件测试案例预览图 组件 <template><div class"context"><div class"top"><div class"label-context"><div class"label" v-for"(item, index) in value" :key"index">…

深度解析Java世界中的对象镜像:浅拷贝与深拷贝的奥秘与应用

在Java编程的浩瀚宇宙中&#xff0c;对象拷贝是一项既基础又至关重要的技术。它直接关系到程序的性能、资源管理及数据安全性。然而&#xff0c;提及对象拷贝&#xff0c;不得不深入探讨其两大核心类型&#xff1a;浅拷贝&#xff08;Shallow Copy&#xff09;与深拷贝&#xf…

【ROS2】初级:CLI工具-使用 rqt_console 查看日志

目标&#xff1a;了解 rqt_console &#xff0c;一种用于内省日志消息的工具。 教程级别&#xff1a;初学者 时间&#xff1a;5 分钟 目录 背景 先决条件 任务 设置在 rqt_console 上的 2 条消息 日志级别 3 摘要 下一步 背景 rqt_console 是用于在 ROS 2 中内省日志消息的 GUI…

【Python实战因果推断】21_倾向分1

目录 The Impact of Management Training Adjusting with Regression 之前学习了如何使用线性回归调整混杂因素。此外&#xff0c;还向您介绍了通过正交化去偏差的概念&#xff0c;这是目前最有用的偏差调整技术之一。不过&#xff0c;您还需要学习另一种技术--倾向加权。这种…

东哥教你如何用Orange Ai pro为家里做一个垃圾分类检测机器

前言 最近入手了一块香橙派&#xff08;Orange Ai Pro&#xff09;的板子&#xff0c;他们的口号是&#xff1a;为AI而生&#xff0c;这让一个算法工程师按捺不住了&#xff0c; 之前主要是在RKNN和ESP32等设备上部署AI模型&#xff0c;看到官方介绍的强大AI算力&#xff0c;很…

how to use Xcode

Xcode IDE概览 Xcode 页面主要分为以下四个部分&#xff1a; 工具栏&#xff08;ToolBar area&#xff09;&#xff1a;主要负责程序运行调试&#xff0c;编辑器功能区域的显示 / 隐藏&#xff1b;编辑区&#xff08;Editor area&#xff09;&#xff1a;代码编写区域&#xf…

前端面试题(CSS篇二)

一、请解释一下 CSS3 的 Flex box&#xff08;弹性盒布局模型&#xff09;&#xff0c;以及适用场景 相关知识点: Flex是FlexibleBox的缩写&#xff0c;意为"弹性布局"&#xff0c;用来为盒状模型提供最大的灵活性。 任何一个容器都可以指定为Flex布局。行内元素也可…

Unity之VS脚本自动添加头部注释Package包开发

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之VS脚本自动添加头部注释Package包开发 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&…

Swift 中的方法调用机制

Swift 方法调用详解&#xff1a;与 Objective-C 的对比、V-Table 机制、Witness Table 机制 在 iOS 开发中&#xff0c;Swift 和 Objective-C 是两种常用的编程语言。尽管它们都能用于开发应用程序&#xff0c;但在方法调用的底层机制上存在显著差异。本文将详细介绍 Swift 的…

CD4017 – 带解码输出的十进制计数器

CD4017 IC 是一个十进制计数器&#xff0c;它有 10 个输出&#xff0c;分别代表 0 到 9 的数字。计数器在&#xff08;14号引脚&#xff09;每个时钟脉冲上升时增加 1。计数器达到 9 后&#xff0c;它会在下一个时钟脉冲时从 0 重新开始。 引脚名称管脚 &#xff03;类型描述VD…

【常用工具】Linux命令行Restful接口调试神器——curl脚本

最近的工作经常要涉及到在Linux服务器端和外部系统联调接口&#xff0c;由于Postman无法在命令行使用&#xff0c;这里浅记一个curl脚本模板&#xff1a; #!/bin/bash # 请求标题 TITLE # token信息 TOKEN # url信息 URL # 请求方式 METHODPOST # Restful请求报文 BODYecho -e…

暑假学习DevEco Studio第2天

学习目标&#xff1a; 掌握页面跳转 学习内容&#xff1a; 跳转页面 创建页面&#xff1a; 在“project”窗口。打开“entry>src>main>ets”,右击“pages”&#xff0c;选择“New>ArkTS File”,命名“Second”&#xff0c;点击回车键。 在页面的路由&#xff0…