算法 - 二叉搜索树每两个节点之间的距离总和,时间复杂度为 O(n)?

2024-03-15

问题是在给定每个父子对间隔单位距离的情况下,找出 BinarySearchTree 中每两个节点之间的距离之和。每次插入后都要计算它。

ex:

 ->first node is inserted..

      (root)

   total sum=0;

->left and right node are inserted

      (root)
      /    \
  (left)   (right)

   total sum = distance(root,left)+distance(root,right)+distance(left,right);
             =        1           +         1          +         2
             =     4

and so on.....

我想出的解决方案:

  1. 蛮力。脚步:

    1. 执行 DFS 并跟踪所有节点:O(n).
    2. 选择每两个节点并计算:O(nC2)_times_O(log(n))=O(n2log(n))他们之间的距离使用最低共同祖先 http://www.geeksforgeeks.org/lowest-common-ancestor-in-a-binary-search-tree/方法并将它们相加。

    总体复杂性:-O(n2log(n)).

  2. O(nlog(n))。脚步:-

    1. 在插入之前执行 DFS 并跟踪所有节点:O(n).
    2. 计算插入节点 与 之间的距离:O(nlog(n))。其余节点。
    3. 将现有总和与步骤 2 中计算的总和相加

    总体复杂性:-O(nlog(n)).

现在的问题是“是否存在以下顺序的解决方案:O(n)??


我们可以通过遍历树两次来做到这一点。

首先我们需要三个数组

int []left它存储左子树的距离之和。

int []right它存储了右子树的距离之和。

int []up它存储父树(没有当前子树)的距离总和。

所以,首先遍历,对于每个节点,我们计算左右距离。如果节点是叶子,则简单地返回0,如果不是,我们可以有这个公式:

int cal(Node node){
    int left = cal(node.left);
    int right = cal(node.right);
    left[node.index] = left;
    right[node.index] = right;
    //Depend on the current node have left or right node, we add 0,1 or 2 to the final result
    int add = (node.left != null && node.right != null)? 2 : node.left != null ? 1 : node.right != null ? 1 : 0;
    return left + right + add;
}

然后,对于第二次遍历,我们需要向每个节点添加距其父节点的总距离。

             1
            / \
           2   3
          / \
         4   5

例如,对于节点 1(根),总距离为left[1] + right[1] + 2, up[1] = 0; (我们加2是因为根有左子树和右子树,它的确切公式是:

int add = 0; 
if (node.left != null) 
    add++;
if(node.right != null)
    add++;

对于节点 2 ,总距离为left[2] + right[2] + add + up[1] + right[1] + 1 + addRight, up[2] = up[1] + right[1] + addRight。原因有一个1公式最后是因为当前节点到他的父节点有一条边,所以我们需要添加1。现在,我表示当前节点的附加距离是add,如果父节点有左子树,附加距离为addLeft和类似地addRight为右子树。

对于节点 3,总距离为up[1] + left[1] + 1 + addLeft, up[3] = up[1] + left[1] + addLeft;

对于节点 4,总距离为up[2] + right[2] + 1 + addRight, up[4] = up[2] + right[2] + addRight;

所以根据当前节点是左节点还是右节点,我们更新up因此。

时间复杂度为O(n)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

算法 - 二叉搜索树每两个节点之间的距离总和,时间复杂度为 O(n)? 的相关文章

  • Java - 从配置文件加密/解密用户名和密码

    我们正忙于为客户开发 Java Web 服务 有两种可能的选择 将加密的用户名 密码存储在Web服务客户端上 从配置中读取 文件在客户端 解密并发送 将加密的用户名 密码存储在 Web 服务器上 从配置中读取 Web 服务器上的文件 解密并
  • 重构——套接字中的良好实践——简单的服务器-客户端 Swing 应用程序

    我使用单例和观察者模式编写了一个带有 Swing 接口的简单服务器 客户端程序 每个客户端都连接到服务器并可以发送消息 服务器将其收到的消息转发给其余的客户端 客户端使用 GUI 允许它们随时连接和断开与服务器的连接 该程序运行得很好 因为
  • 如何降低圈复杂度?

    我正在开发一个将 RequestDTO 发送到 Web 服务的类 我需要在发送请求之前验证该请求 请求可以从 3 个不同的地方发送 并且每个 请求类型 有不同的验证规则 例如请求1必须有姓名和电话号码 请求2必须有地址等 我有一个 DTO
  • java中队列的实现

    在 Java 中实现队列是一个非常常见的面试问题 我在网上冲浪 看到了许多实现 他们做了一些奇特的事情 比如实现队列接口和编写自己的addLast and removeFirst 方法 我的问题是我不能使用LinkedList 类并使用其预
  • 如果按下 Esc 则中断循环

    我用 JAVA 语言编写了一个程序 它使用 Scanner 类接受来自控制台的输入 现在我想将此功能添加到我的代码中 以便在用户按下 Esc 按钮时存在循环 while 到目前为止 我认为键盘类可以帮助我 但它就像扫描仪一样 我尝试使用事件
  • Hystrix是否可以订阅CircuitBreaker开启事件?

    对于单元测试 我希望能够订阅 Hystrix 事件 特别是在断路器打开或关闭时发生事件 我四处寻找示例 似乎解决方法是利用指标流并监视断路器标志 由于 Hystrix 是基于 RxJava 构建的 我认为应该在某个地方有一个事件订阅接口 在
  • JavaFx 中装饰且不可移动的舞台

    我想在 JavaFx 中创建一个装饰舞台 它也将不可移动 我正在从另一个控制器类创建这个阶段 我能够创造和展示舞台 但它是自由移动的 我怎样才能创建这个 非常感谢帮助和建议 我把打开新关卡的方法贴出来 private void addRec
  • Scala(或 Java)中泛型函数的特化

    是否可以在 Scala 中专门化泛型函数 或类 例如 我想编写一个将数据写入 ByteBuffer 的通用函数 def writeData T buffer ByteBuffer data T buffer put data 但由于 put
  • Java 中 static 关键字如何工作?

    我正在阅读Java教程 http docs oracle com javase tutorial index html从一开始我就有一个问题static字段或变量上的关键字 作为Java said here http docs oracle
  • 在多模块项目中访问绑定适配器

    我有一个多模块项目 其中应用程序模块包含我的绑定适配器 而我的功能模块取决于我的应用程序模块 因为它是动态功能模块 应用程序 包含绑定适配器 gt 动态功能模块 存在布局的地方 我在所有模块中启用了数据绑定和 kapt 我无法成功构建应用程
  • 删除 ArrayList 对象问题

    我在处理作业时遇到从 ArrayList 中删除对象的问题 如果我使用 正常 for 循环 它的工作原理如下 public void returnBook String isbn for int i 0 i lt booksBorrowed
  • 为什么 RMI 注册表忽略 java.rmi.server.codebase 属性

    我正在运行 java RMI 的 Hello World 示例 1 我在空文件夹中运行注册表 motta motta laptop tmp rmiregistry 2 我启动 HTTP 服务器以在运行时检索类 下载文件夹包含客户端 服务器的
  • Java 8根据Map属性过滤Map对象列表以删除一些重复项

    Have a List
  • 删除队列中的最后一个元素

    我需要删除队列的最后一个元素 我唯一可以使用的操作是 Peek 获取第一个元素而不删除它 Enqueue element 向队列末尾插入一个元素 Dequeue 删除第一个元素 IsEmpty true 或 false 队列是否为空 而且我
  • 如何使用maven创建基于spring的可执行jar?

    我有一个基于 Maven 的 Spring WS 客户端项目 我想将其打包为单个 jar 在eclipse中 一切运行正常 当我尝试将其打包为可执行 jar 时 我收到 ClassNotFound 异常 因为 Spring jar 未包含在
  • 无法在 BlackBerry Playbook 上设置音量

    我在更改黑莓游戏书的音量时遇到问题 首先 我将 Android 应用程序重新打包到 Palybook 应用程序 我需要使用搜索栏更改黑莓剧本的音量 并在搜索监听器中设置音频管理器音量 这是代码 audioManager AudioManag
  • BoneCP 和 Derby - 如何正确关闭

    I have BoneCP CONNECTION POOL CONNECTION POOL getConfig setJdbcUrl jdbc derby database shutdown true Connection connecti
  • 如何将无向图转换为 DAG?

    The 维基页面 http en wikipedia org wiki Directed acyclic graph Relation to other kinds of graphs says 任何无向图都可以通过为其顶点选择总顺序并将每
  • C/C++ 通过 Android NDK 在 JNI 中看不到 Java 方法

    我正在尝试从使用 NDK 构建的 C 类文件调用 Java 方法 它不断抛出常见的 未找到非静态方法 错误并导致整个 Android 应用程序崩溃 下面的代码片段 有些东西可能不需要 但我按原样保留它们 因为焦点 问题在于refreshJN
  • Java:基于 Web 的应用程序中的单例类实例

    我在 Web Application 中有这个 Singleton 类 public class MyDAO private static MyDAO instance private MyDAO public static MyDAO g

随机推荐

  • 双向数据绑定不更新 UI

    我试图理解为什么设置值不会自动刷新用户界面 如果我调用 binding setItem UI 就会刷新 我知道绑定对象包含更新的值 但在设置 item name 和 item checked 后 UI 没有刷新 我究竟做错了什么 我需要每次
  • 如何在flutter中显示全屏图像

    有什么办法可以显示全屏图像吗 var imagejadwal new Image network https firebasestorage googleapis com v0 b c smp bruder appspot com o fo
  • yii:使用查询生成器选择总和

    我尝试执行一个简单的查询 如下所示 tot Yii app gt db gt createCommand gt select sum field gt from products gt where id id gt queryRow 但 t
  • Gradle 依赖项 - 最新快照

    我有一个 gradle 多项目构建 在一个项目中 我定义了对其他 JAR 的一些依赖项 并使用 始终依赖于 JAR 的最新版本 例如 runtime group com app name core version 这非常有效 每当我重新构建
  • jQuery:.ready() 和 .ajaxComplete

    我希望我的 JS 的某些部分在文档准备好或 ajax 查询完成时初始化像这样的东西 if document ready or document ajaxComplete do something 这样的条件可以写吗 我该如何做才正确呢 你可
  • C 中的快速 2D 卷积

    我正在尝试用 Python 实现卷积神经网络 最初 我使用 scipy signal 的 convolve2d 函数来进行卷积 但它有很多开销 而且用 C 实现我自己的算法并从 python 调用它会更快 因为我知道我的输入是什么样的 我实
  • 由于Android 6.0监听PhoneStateListener.LISTEN_DATA_CONNECTION_STATE的变化似乎不再需要READ_PHONE_STATE权限

    我正在将 Android 6 0 运行时权限应用到一个应用程序中 该应用程序侦听运营商数据连接状态更改 我首先尝试从清单中删除 READ PHONE STATE 以检查应用程序需要权限的位置 令我惊讶的是 该应用程序根本没有崩溃 此后 我在
  • OAuth 授权码何时到期?

    我知道 在 OAuth 中使用授权代码 授权代码 时 访问令牌的生命周期应该很短 但刷新令牌的生命周期可以很长 所以我为我的项目决定 访问令牌生命周期 1 天 刷新令牌生命周期 30 天 但授权码的典型生命周期是多长 我认为它应该非常非常短
  • go中如何连接Oracle

    我认为有两种方法可以在 Go 中连接到 Oracle DB 在 Windows 上 github com tgulacsi goracle github com mattn go oci8 但对于我这个水平的人 开源 golang的初学者
  • Liferay DLFileEntryLocalServiceUtil.addFileEntry 不创建 AssetEntry 记录

    我有一个自定义 portlet 它提供了一个用户可以上传文件的表单 上传的文件应存储在文档和媒体 Portlet 中 我正在使用创建文件条目DLFileEntryLocalServiceUtil addFileEntry 文件上传成功 记录
  • NSTask、命令行工具和 root

    我正在开发一个需要使用 dd 的应用程序 我使用应用程序包中的 shell 脚本来执行此操作 该脚本从应用程序本身收集参数 进行一些检查 然后启动 dd 为了进行此操作 我需要使用 root 调用 dd 并且我已经在 StackOverfl
  • iPhone 中社交网络与 OAuth 的集成

    我是 iPhone 编程新手 有人可以解释一下什么是 OAuth 以及它如何在社交网络集成中使用吗 有多少社交网站提供 API Use ShareKit http getsharekit com
  • 如果行包含重复数据,如何突出显示?

    我有以下数据 id number colour 1766 53 red 1767 3 green 1768 202 green 1769 52 blue
  • 查找最深子树节点的级别

    我有树节点 我想找到树节点中最深的子节点 如果有 2 个子节点level 11 level 13分别然后我需要函数返回值13 我怎样才能做到这一点 public int FindLevel TreeNode oParentNode coun
  • 获取 std::function 的名称

    在下面的玩具示例中 我想获取函数的名称 该函数本身被给出为std function争论 在C 中是否可以获取a的名称std function object void printName std function
  • 重新分配变体

    只是为了定位上下文 它是关于一个字符串池 意味着一个带有字符串键的哈希表 实际上是知道其长度的特殊字符串 但我想这个细节在这里无关紧要 重点是当池需要增长时调整列表数组 用作表桶 的大小 但是 这是核心细节 包含字符串的单元格实际上位于单元
  • 如何在代码中向 ActionBar 操作添加子菜单项?

    通过 xml 我可以将子菜单项添加到我的操作中ActionBar main menu xml menu menu
  • BizTalk 2009 上的意外绑定重置

    我在 BizTalk 2009 上使用了许多应用程序 我多次注意到 在随机应用程序中添加资源 dll 后 精确应用程序的所有绑定 自定义管道 都会完全重置为之前的早期状态 我真的很好奇为什么会发生这种情况 但我还需要一个解决方案来阻止该行为
  • 使用 Powershell 将字符串转换为特定时区的 DateTime 对象

    由于我对 Powershell 的了解有限 我试图将当前的字符串转换为 2020 01 23 10 06 07 时区中的日期时间对象Eastern Standard Time 最终我希望能够使用与 UTC 的正确偏移量格式化为 ISO860
  • 算法 - 二叉搜索树每两个节点之间的距离总和,时间复杂度为 O(n)?

    问题是在给定每个父子对间隔单位距离的情况下 找出 BinarySearchTree 中每两个节点之间的距离之和 每次插入后都要计算它 ex gt first node is inserted root total sum 0 gt left