- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在一棵有根带权树中,如何找到距每个节点一定距离内的节点数?您只需要考虑向下边缘,例如节点从根向下。请记住,每条边都有一个权重。
我可以在 O(N^2)
时间内使用每个节点的 DFS 并跟踪行进的距离来完成此操作,但是 N >= 100000
有点慢。我很确定您可以使用 DP 使用未加权的边缘轻松解决它,但是有人知道如何快速解决这个问题吗? (小于 N^2
)
最佳答案
可以通过以下观察改进我之前对O(nlog d) 时间 和 O(n) 空间的回答:
The number of sufficiently-close nodes at a given node v is the sum of the numbers of sufficiently-close nodes of each of its children, less the number of nodes that have just become insufficiently-close.
我们将距离阈值称为 m,并将两个相邻节点 u 和 v 之间的边缘距离称为 d(u, v)。
对于每个节点 v,我们将维护一个初始值为 0 的计数 c(v)。
对于任何节点 v,考虑从 v 的父节点到根节点的祖先链。将此链中的第 i 个节点称为 a(v, i)。请注意,在该链中第一个节点的某个数字 i >= 0 中,需要将 v 算作足够接近,而在其他节点中则不需要。如果我们能够快速找到 i,那么我们可以简单地递减 c(a(v, i+1))(使其(可能进一步)低于 0),这样当 a 的计数(v, i+1) 的 child 在后面的过程中被添加到它,v 被正确地排除在计数之外。如果我们在将节点 v 的所有子节点添加到 c(v) 之前计算出完全准确的计数,则任何此类排除都会正确地“传播”到父节点计数。
棘手的部分是有效地找到 i。调用从v到根s(v, j)的路径上前j >= 0条边的距离之和,调用这些路径长度的所有depth(v)+1的列表,按升序排列, s(v)。我们要做的是对路径长度列表 s(v) 进行二分搜索,寻找大于阈值 m 的第一个条目:这将在 log(d) 时间内找到 i+1。问题是构建 s(v)。我们可以使用从 v 到根的运行总数轻松地构建它——但这将需要每个节点的 O(d) 时间,从而抵消任何时间改进。我们需要一种在恒定时间内从 s(parent(v)) 构造 s(v) 的方法,但问题是当我们从节点 v 递归到它的子节点 u 时,路径长度“以错误的方式”增长:每个path length x需要变成x + d(u, v),并且需要在开头添加一个新的path length 0。这似乎需要 O(d) 更新,但有一个技巧可以解决这个问题......
解决方案是在每个节点 v 处计算从 v 到根的路径上所有边的总路径长度 t(v)。这很容易在每个节点的恒定时间内完成:t(v) = t(parent(v)) + d(v, parent(v))。然后,我们可以通过在 s(parent(v)) 的开头加上 -t 来形成 s(v),并且在执行二分查找时,将每个元素 s(v, j) 视为表示 s(v, j) + t (或者等效地,二进制搜索 m - t 而不是 m)。通过让节点 v 的子节点 u 共享 v 的路径长度数组,可以在 O(1) 时间内在开头插入 -t,其中 s(u) 被视为在 s(v) 之前开始一个内存位置。所有路径长度数组都在大小为 d+1 的单个内存缓冲区内“右对齐”——具体来说,深度为 k 的节点的路径长度数组将从缓冲区内的偏移量 d-k 开始,以便为其后代节点预留空间条目。数组共享意味着兄弟节点将覆盖彼此的路径长度,但这不是问题:我们只需要 s(v) 中的值在前序 DFS 中处理 v 和 v 的后代时保持有效。
通过这种方式,我们获得了 O(d) 路径长度在 O(1) 时间内增加的效果。因此,在给定节点找到 i 所需的总时间是 O(1)(构建 s(v))加上 O(log d)(使用修改后的二分查找找到 i)= O(log d)。单个预序 DFS 遍用于查找和递减每个节点的适当祖先的计数;后序 DFS 通过然后将子计数加到父计数中。可以将这两个过程组合成对节点的单一过程,在递归之前和之后执行操作。
关于algorithm - 在有根树中查找一定距离内的节点数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13905223/
过去两天我遇到了一个奇怪的问题,但我还无法解决它。我正在尝试从 2 个文本文件中获取单词并将这些单词添加到树中。我选择的获取单词的方法引用这里: Splitting a text file into
例如,像这样的树: 5 / \ 3 6 / \ 7 2 print(tree.branchLenSum()) 将是1+1+2+2=6 树类: class BinaryTre
我正在学习 JavaScript。我是文档对象模型 (DOM) 主题的新手。 我对节点在 DOM 树中的布局方式感到困惑? 我使用了这个 HTML 文件。 List Buy groceries
这个问题不太可能对任何 future 的访客有帮助;它只与一个较小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于全世界的互联网受众。如需帮助使此问题更广泛适用,visit the
var nodeEnter = node.enter().append("g") .attr("class", "node") .attr("transform", function (d) {
我正在使用数据表来表示我的应用程序中的数据。我有一个功能,可以在单击克隆图标时克隆任何行并动态添加它下面的行。 数据表具有搜索功能,可以搜索表中存在的所有行,但是它只考虑初始页面加载时加载到表中的行。
我已经用 Python 编写了一个 Tree 类,但是我在为它创建迭代器时遇到了问题我希望能够做到 phonebook = MyTree() # Build up tree for node in p
我需要为 FreeBSD 检查这个 libunwind 端口, http://people.freebsd.org/~kib/git/libunwind.git/ 我以前和当我尝试使用命令 check
我已经实现了自己的 AVL 树,并将其用作字典。我想知道,计算以某个字符串开头的所有单词的最快方法是什么。 例如: string prefix = "fa"; output: 4 我已经在 O(n)
我目前正在尝试编写一个使用 2-3-4 树的程序,但我遇到了插入函数的问题。这是相关代码.. int main () { tree234 myTree; myTree.insert("
我的同事问了我这个问题,但我无法想出任何最佳解决方案。 给定一棵具有n 个节点、n-1 条边和 q 个查询的无向加权树。 每个查询都有输入 u v k ,输出位于路径 u to v 的奇数且小于 k
如果我有一个 app.html 模板如下: ${message} test 使用 MyComponent.ts : export class MyComponent { my
我继承了一个 git 存储库,其中树中的提交条目为空 sha1,阻止 FishEye 为存储库编制索引。 $ git fsck Checking object directoriies: 100%(2
这是一个例子。我也许可以在点击函数中弄清楚它,但我不确定从点击函数外部从根开始检查所有子项的最佳方法。谢谢 .node circle { fill: #fff; stroke: stee
我正在使用 Python 批量编辑许多当前看起来像这样的 musicXML 文件: ... -5 -9
假设有一个 8 阶 B 树。这意味着它可以有 8 个指针和 7 个元素。假设字母 A 到 G 存储在这棵 B 树中。所以这棵 B 树只是一个包含 7 个元素的节点。 然后你尝试将 J 插入到树中。没有
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我正在尝试做一个简单的二维“物理”模拟,主要涉及圆形物体的碰撞,为了避免编程我自己的空间索引(四叉树/r-tree/等),我希望使用 Boost 的 R -树。 问题是我在 Boost 文档中找不到任
我正在从 python 字典中读取数据并尝试在下面的树中添加更多书籍元素。下面只是一个示例,我需要复制一个元素及其子元素但替换内容,在这种情况下我需要复制 book 元素但替换标题和作者。
假设我有一个变量,它包含一个 nltk 树类的树。是否有类似 parent() 或返回节点父节点的函数? 最佳答案 您需要一种不同的数据结构:一棵树,其节点包含指向其父节点的指针。 NLTK 现在提供
我是一名优秀的程序员,十分优秀!