二叉树的堂兄弟节点——深度优先搜索+广度优先搜索

news2024/9/21 19:04:04

二叉树的堂兄弟节点

在这里插入图片描述

题目描述

在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。

如果二叉树的两个节点深度相同,但 父节点不同 ,则它们是一对堂兄弟节点。

我们给出了具有唯一值的二叉树的根节点 root ,以及树中两个不同节点的值 x 和 y 。

只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true 。否则,返回 false。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/cousins-in-binary-tree

image-20230627103632333

image-20230627103645636

提示:

二叉树的节点数介于 2 到 100 之间。
每个节点的值都是唯一的、范围为 1 到 100 的整数。

解题思路

这道题目可以通过遍历二叉树来查找节点 x 和 y,并分别记录它们的深度和父节点。如果它们深度相同但父节点不同,那么它们是堂兄弟节点,返回 true。如果二者之一未找到或深度不同,则返回 false。

具体的实现可以使用深度优先搜索或广度优先搜索来遍历二叉树。在遍历二叉树的过程中,需要记录当前节点的深度和父节点,以便在找到目标节点时方便判断是否为堂兄弟节点。

具体步骤如下:

  1. 定义一个存储节点深度和父节点信息的字典。
  2. 使用深度优先搜索或广度优先搜索遍历整个二叉树,同时记录每个节点的深度和父节点。
  3. 找到节点 x 和 y,分别记录它们的深度和父节点。
  4. 判断它们的深度是否相同,且父节点是否不同。如果满足条件,则返回 true,否则返回 false。

需要注意的是,这道题目中提到的二叉树具有唯一值的特点,因此不需要处理节点值相同的情况。

深度优先搜索

深度优先搜索(Depth First Search, DFS) 是一种基于栈或递归的搜索算法,可用于遍历或搜索树、图或其他数据结构。该算法从起点开始,不断沿着已访问但未遍历所有邻居的点向前查找,直到找到终点或达到搜素边界。当不能继续前进时,该算法回溯到最近的未访问遍历所有邻居的点,继续搜索直至找到终点。

在深度优先搜索过程中,算法递归访问每一个节点,并在访问一个节点时,将其标记为已访问。然后,算法从当前节点开始,沿着某个分支一直访问下去,只有当到达某个节点时发现它没有未访问的邻居节点时,算法才回溯到上一个节点,尝试其他的分支。

深度优先搜索算法简单易用,其实现方式既可以使用栈,也可以使用递归。它在搜索树或图中具有广泛的应用,例如可用于寻找连通块、寻找最短路径、拓扑排序、生成随机树等。其时间复杂度为 O(V+E),其中 V 表示节点数,E 表示边数。

深度优先搜索可以应用于图、树或其他数据结构的遍历和搜索问题,包括以下范围:

  1. 有向无环图(Directed Acyclic Graph, DAG)的拓扑排序。
  2. 连通性问题,例如求解连通块、最短路径、所有路径等。
  3. 生成随机树(Random Tree)。
  4. 检测环(Cycle Detection)。
  5. 检查图是否为二分图(Bipartite Graph)。
  6. 解决迷宫问题(Maze Problem)。
  7. 在学习和人工智能领域中,用于搜索特定模式或满足特定条件的状态空间。

除了上述范围之外,深度优先搜索还可以在其他类型的问题上发挥作用,例如,在博弈搜索问题中,可以使用深度优先搜索解决棋局状态的搜索。但是,深度优先搜索不适合解决一些特定的搜索问题,例如需要找到最优解或解决动态规划问题,因为它 不保证找到最短路径。

广度优先搜索

广度优先搜索(Breadth First Search, BFS)是一种基于队列的搜索算法,可用于遍历或搜索树、图或其他数据结构。该算法从起点开始,按照距离逐层向外探索,直到找到终点或遍历完整张图。

在广度优先搜索过程中,算法首先访问起点并将其加入队列中。然后从队列中取出下一个节点并访问其所有未访问过的相邻节点,将其加入队列中。不断重复此过程,直到找到终点或队列为空。此时,算法的搜索过程就结束了。

相比于深度优先搜索,广度优先搜索能够确保找到的路径是离起点最近的路径,但一般情况下需要更多的空间用于存储节点和边相邻节点信息。

广度优先搜索算法的时间复杂度为 O(V+E),其中 V 表示节点数,E 表示边数。算法的实现通常使用队列进行辅助,存储已经访问的节点。在实现过程中,需要额外记录每个节点到起点的距离,以便在搜索到目标节点时能够返回最短路径。广度优先搜索也可以应用于迷宫问题、最短路径问题和网络图等复杂应用中。

广度优先搜索可以应用于图、树或其他数据结构的遍历和搜索问题,包括以下范围:

  1. 求解最短路径问题(Shortest Path Problem)。
  2. 求解迷宫问题(Maze Problem)。
  3. 求解通信网络问题(Communication Network Problem)。
  4. 解决状态转移问题(State-Transition Problem),例如在人工智能领域中寻找最优解的问题。
  5. 实现拓扑排序(Topological Sorting)。
  6. 对存储结构为邻接矩阵或邻接表的图进行宽度搜索。
  7. 在搜索过程中,求解度数、连通性、直径和关键路径等问题。

总之,广度优先搜索可以应用于需要查找节点距离的问题,或者需要在图或树中搜索离起点最近的节点的问题。 与深度优先搜索不同,广度优先搜索通常更适用于搜索最短路径和计算节点之间的最短距离等问题。

题目解法

可以通过深度优先搜索和广度优先搜索两种方式来解决该问题。

首先,我们通过深度优先搜索找到x和y的父节点以及深度信息。然后,比较x和y的深度是否相同且它们的父节点是否不同,如果是,则它们是一对堂兄弟节点。

以下是使用深度优先搜索的Python代码:

class Solution:
    def isCousins(self, root, x, y):
        def dfs(node, parent, depth, val):
            if not node:
                return
            if node.val == val:
                return parent, depth
            return dfs(node.left, node, depth+1, val) or dfs(node.right, node, depth+1, val)

        x_info = dfs(root, None, 0, x)
        y_info = dfs(root, None, 0, y)

        return x_info[0] != y_info[0] and x_info[1] == y_info[1]

image-20230627103729015

另一种方式是使用广度优先搜索,通过层序遍历二叉树找到x和y的深度和父节点。最后,比较x和y的深度是否相同且它们的父节点是否不同,如果是,则它们是一对堂兄弟节点。

以下是使用广度优先搜索的Python代码:

class Solution:
    def isCousins(self, root, x, y):
        queue = [(root, None)]
        x_info = None
        y_info = None
        depth = 0
        while queue:
            depth += 1
            for i in range(len(queue)):
                node, parent = queue.pop(0)
                if node.val == x:
                    x_info = (parent, depth)
                if node.val == y:
                    y_info = (parent, depth)
                if node.left:
                    queue.append((node.left, node))
                if node.right:
                    queue.append((node.right, node))
            if x_info and y_info:
                break

        return x_info[0] != y_info[0] and x_info[1] == y_info[1]

image-20230627103804224

深度优先搜索算法优化

对于上述算法,也可以进行一些细节上的优化。比如,在递归时,可以首先判断左子树是否存在x或y,如果存在就不需要递归右子树了;反之,如果右子树存在x或y,也不需要递归左子树了。这样可以减少一些递归次数。

另外,可以使用Python中的tuple解包来获取x和y的信息,而不是使用下标来访问。

以下是进一步优化后的代码:

class Solution:
    def isCousins(self, root, x, y):
        def dfs(node, parent, depth, val):
            if not node:
                return
            if node.val == val:
                return (parent, depth)
            left_info = dfs(node.left, node, depth+1, val)
            if left_info:
                return left_info
            right_info = dfs(node.right, node, depth+1, val)
            if right_info:
                return right_info

        x_parent, x_depth = dfs(root, None, 0, x)
        y_parent, y_depth = dfs(root, None, 0, y)

        return x_parent != y_parent and x_depth == y_depth

优化后的算法更加简洁,也更加高效。不仅可以正确地判断x和y是否为堂兄弟节点,还可以避免不必要的遍历,提高代码的效率。

image-20230627103838471

广度优先搜索算法优化

可以对上述算法进行以下优化:

  1. 如果找到了x和y的信息,就可以直接返回结果,避免继续执行不必要的循环。

  2. 如果深度已经不同了,就不需要再继续遍历,可以直接返回结果。

以下是优化后的代码:

class Solution:
    def isCousins(self, root, x, y):
        queue = [(root, None)]
        x_info = None
        y_info = None
        depth = 0
        while queue:
            depth += 1
            for i in range(len(queue)):
                node, parent = queue.pop(0)
                if node.val == x:
                    x_info = (parent, depth)
                if node.val == y:
                    y_info = (parent, depth)
                if x_info and y_info:
                    break
                if node.left:
                    queue.append((node.left, node))
                if node.right:
                    queue.append((node.right, node))
            if x_info and y_info:
                break

        return x_info[0] != y_info[0] and x_info[1] == y_info[1] and depth == x_info[1]

由于优化后的代码在找到x和y的信息时就可以直接返回结果,因此效率更高。

image-20230627103904611

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

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

相关文章

实现分布式事务的新标杆:RocketMQ的全面解析与应用指南

在分布式系统中,实现事务的一致性和可靠性是一项重要的挑战。本文将详细介绍如何利用 RocketMQ 的半消息机制来实现分布式事务,并提供具体的代码示例和最佳实践。 1. 引言 在分布式系统中,事务处理是一项复杂而关键的任务。传统的 ACID 事务…

基于SpringCloud微服务毕业论文管理系统设计与实现

一、概述 1.1 课题背景及意义 随着学校不断扩大和学生人数的猛增,关于各类教学信息也越来越多。毕业论文的管理也成为了不可避免的一道关卡,学生需要及时获取论文相关进度,学校的管理者要求能方便对论文进行处理。基于这些需求,开发一个实用的微服务管理系统,以满足双方…

13-使用调度框架quartz,为系统增加定时调度功能

1 、创建后端模块batch 1.1、创建maven项目 1.2、pom.xml文件中导入依赖 <dependencies><!-- common--><dependency><groupId>com.wei</groupId><artifactId>common</artifactId></dependency><!-- 热部署…

电磁兼容常用测量单位及转换关系 dB、dBm、dBw、dBμV、dBmV、dBV、dBA等单位介绍

目 录 摘要分贝简介分贝在EMC测试中电磁兼容常用测量单位常用线性单位的对数转换单位间转换基于50Ω额定阻抗的电压、电流和功率单位间的换算基于50Ω额定阻抗的场强单位间的换算 单位换算的应用参考文献总结 摘要 为获得更大的相对幅度显示范围&#xff0c;电磁兼容测试常使用…

Graalvm Native Image 元数据适配

Graalvm Native Image 元数据适配 本文章主要叙述在 Java 应用适配 Graalvm Native Image 中的步骤和遇到的一些问题&#xff01;因为 Graalvm 官方文档相关概念叙述过于简单。基本靠问才能知道些许有用信息。所以写此文章。 关于 Graalvm 基础知识的相关学习&#xff0c;可以…

部署 LAMP平台Linux,Apache,MySQL ,PHP源码编译安装

目录 一、.LAMP简介与概述 1.LAMP平台概述 2. 构建LAMP平台顺序 3. 编译安装的优点 4. 各组件作用 5. 数据流向 二、编译安装Apache httpd服务 1.关闭防火墙&#xff0c;将安装Apache所需软件包传到/opt目录下 2.安装环境依赖包 3.配置软件模块 4.编译及安装 5.优…

chatgpt赋能python:Python获取父类:探究继承关系的技巧

Python获取父类&#xff1a;探究继承关系的技巧 Python是一种高级编程语言&#xff0c;它被广泛用于Web开发、数据分析、人工智能等领域。Python的面向对象编程是其特色之一。在面向对象编程中&#xff0c;我们经常需要使用继承关系来定义不同类之间的关系。在这篇文章中&…

小程序学习(一):基本知识点笔记

1.小程序与普通网页开发的区别 1.运行环境不同 网页运行在浏览器环境中 小程序运行在微信环境中 2.API不同 由于运行环境的不同,小程序无法调用DOM和BOM的API。 但是,小程序中可以调用微信环境提供的各种API,例如:地理定位、扫码、支付... 3.开发模式不同 网页的开发模式:浏览器…

C语言笔记-4 输入输出

目录 输入输出简单举例scanf()getchar()putchar()puts()gets() 标准文件%d 格式化输出整数%f 格式化输出浮点型数据 getchar() & putchar() 函数gets() & puts() 函数scanf() 和 printf() 函数 输入输出 简单举例 scanf() 空格、回车也是字符&#xff0c;下面情况也…

APP盲盒系统开发前端后台详细功能讲解

一、栏目 功能 说明 登录注册 注册 输入手j号&#xff0c;获取验zm&#xff0c;输入密m 密码登录 手机号密码 忘记密码 输入手j号&#xff0c;获取y证m&#xff0c;输入新m码 底部导航 开盲盒、寄售中心、商城、个人中心 开盲盒 显示盲盒 可滑动更换其他盲盒 立即开盒 点…

从程序员到架构师——数据持久化层场景

全文摘自&#xff1a;从程序员到架构师&#xff08;王伟杰著&#xff09; 购买链接&#xff1a;https://item.jd.com/13626926.html 程序员之间的能力差异在哪里&#xff1f;如果是学技术&#xff0c;大家可以阅读同样的书籍和网络文章&#xff0c;为什么还会造成最终专业能力的…

SC7515运算放大器(OPA)可pin对pin兼容AD8138

对于一般运算放大器&#xff0c;SC7515 在差分信号处理方面获得了巨大进步。SC7515 即可以用作单端至差分放大器或也可以差分至差分放大器&#xff0c;像运算放大器一样易于使用&#xff0c;并且大大简化了差分信号放大与驱动。可pin对pin兼容AD8138。该放大器输入噪声低、-3 d…

Spring之BeanFactory与ApplicationContext区别、实例化Bean的三种⽅式、延迟加载(lazy-Init )

Spring IoC进阶 IOC之BeanFactory与ApplicationContext区别启动 IoC 容器的方式 实例化Bean的三种⽅式使用无参构造方法实例化工厂静态方法实例化工厂实例方法实例化 Spring IOC之延迟加载(lazy-Init )Bean的延迟加载&#xff08;延迟创建&#xff09;应用场景 IOC之BeanFactor…

案例分享|梅雨季的机房湿度问题如何解决?

6月底&#xff0c;和Q3的KPI一起赶来的是南方的梅雨季。 持续不断的降雨&#xff0c;使空气湿度一度高达75%-80%&#xff0c; 南方人正式开启高温酷暑下的桑拿模式。 高温高湿除了带来体感不适&#xff0c;还会导致心情抑郁、烦燥、易疲倦...... 毕竟&#xff0c;与此强相关…

Sentinel spring的全局异常处理器,导致熔断规则(异常数规则)失效解决方案

最近在使用sentinel过程中发现&#xff0c;如果使用springboot的RestControllerAdvice全局异常捕获&#xff0c;那么设置sentinel的异常数熔断规则就会失效&#xff0c;去github上看sentinel的Issues发现已经有人提过这问题&#xff0c;官方也是没有正面回复 官方文档更不用说&…

matlab之table Excel对大量数据的缺失

Excel表格对于数据量的限制 ####### matlab之table table好处&#xff0c;可完整保留导入数据&#xff0c;不限于数值 matlab中table的切片等操作

C/C++编程安全标准GJB-8114解读——声明定义类

软件检测实验室在建立软件测试体系或申请cnas/cma相关资质时&#xff0c;需要依据相关标准&#xff0c;使用有效的方法开展检验检测活动&#xff0c;GJB-8114是一部嵌入式软件安全测试相关的国家标准&#xff0c;本系列文章我们就针对GJB-8114《C/C语言编程安全子集》的具体内容…

js逆向-md5加密算法逆向-案例网站

今天逆向的网站&#xff1a;aHR0cHM6Ly9mYW55aS55b3VkYW8uY29tL2luZGV4Lmh0bWwjLw &#xff08;去在线网站进行base64解密即可&#xff09; 1、点击翻译&#xff0c;触发请求 可以看到sign参数加密&#xff0c;加密长度为32为 md5加密特征&#xff1a; **长度固定。**无论输…

基于树莓派4B的YOLOv5-Lite目标检测的移植与部署(含训练教程)

前言&#xff1a;本文为手把手教学树莓派4B项目——YOLOv5-Lite目标检测&#xff0c;本次项目采用树莓派4B&#xff08;Cortex-A72&#xff09;作为核心 CPU 进行部署。该篇博客算是深度学习理论的初步实战&#xff0c;选择的网络模型为 YOLOv5 模型的变种 YOLOv5-Lite 模型。Y…

记一次解决vmware安装windows server 2019时, 虚拟机网络电缆被拔出,连不上网的问题

项目场景&#xff1a; 项目需要基于electron开发桌面端软件&#xff0c;实现前后端项目的自动化部署、可视化配置等功能&#xff0c;经过需求分析后&#xff0c;确定首先要适配的场景即&#xff1a;通过桌面端软件远程连接&#xff0c;在桌面端软件中执行安装、运行、配置等一…