问题是如何创建一个二叉树,给定它的祖先矩阵。我在http://www.ritambhara.in/build-binary-tree-from-ancestor-matrics/找到了一个很酷的解决方案。问题是它涉及从矩阵中删除行和列。现在我该怎么做?任何人都可以为此建议一个伪代码吗?或者,有没有更好的算法?
答案 0 :(得分:2)
您不必实际删除行和列。你可以在一些额外的数组中将它们标记为已删除,或者你可以将它们全部为零,我认为它们实际上是相同的(实际上,你仍然需要知道它们被删除了,所以你不要选择它们再次在步骤4.c - 所以,将节点标记为已删除应该足够好了。
以下是页面中对伪代码的修改:
4.B。
used[temp] = true;
for (i = 0 to N)
Sum[i] -= matrix[i][temp]; (aka decrement sum if temp is a predecessor of i)
matrix[i][temp] = 0;
4.C。查找Sum [i] == 0并使用[i] == false。
的所有行答案 1 :(得分:2)
这让我想起了Doanld Knuth用来实现Dancing Links的Algorithm X
它基本上是一个循环双链表的结构。 您可以维护一个单独的 Sum 数组,并根据需要删除行和列来更新它。
实际上,您不需要维护单独的 Sum 数组 修改强>
我的意思是 -
您可以使用由圆形2D链接列表组成的结构。
节点结构有点像:
struct node{
int val;
struct node *left;
struct node *right;
struct node *down;
};
最顶部和最左侧列表是顶点的标题列表(二叉树节点值)。
如果顶点j
是顶点i
的祖先,则构建一个(空)新节点,以便为j
列的当前down
分配此新节点并{{ 1}}为这个新节点分配当前i's
。
注意:通过从左到右扫描祖先矩阵的每一行并插入从0到N的行,可以很容易地构建结构。(假设{{1这里是顶点的数量)
我从Image1和Image2借用了这些图片,以便了解网格。第二张图片缺少最左边的标题。
如果left
为否。顶点。祖先矩阵(如果树偏斜)或平均N
条目可能有更差N
个条目。
要搜索当前的根目录:O(N^2)
假设一个虚拟节点开始,线性扫描最左边的头并选择一个O(NlogN)
的节点。
删除此顶点信息:O(N)
删除行:node->down->right == node->down
O(N)
删除专栏:O(1)
转到相应的列 - 说(p):
node->down = node->down->down;
在发现当前Root之后,您可以将其分配给它的父节点并将它们插入到队列中,以根据该链接建议您处理下一级别。
总时间复杂度:N +(N-1)+(N-2)+ .... = O(N)
。
最差的案例空间复杂度node* q = p;
while(q->down != p){
q->down->left->right = q->down->right;
q->down->right->left = q->down->left;
q = q->down;
}
虽然从已有的解决方案中渐近运行时没有大的改进。我认为这值得一提,因为这种结构对于存储稀疏矩阵和定义像它们的乘法等操作特别有用,或者如果你正在使用一些回溯算法来删除一行/列,然后再回溯并像Knuth一样再次添加它AlgorithmX。
答案 2 :(得分:0)
您不必更新矩阵。只是递减当前节点的任何后代的sum数组中的值,并检查它们中的任何一个是否达到零,这意味着当前noe是最后一个祖先,例如,直接父母:
QTextEdit