【发布时间】:2021-10-10 16:07:25
【问题描述】:
我得到了一个练习,要求我创建一个算法,计算树中给定高度处的所有节点,其中高度定义为“节点的高度是从节点到更远的节点的最大距离叶”(我不能使用其他数据结构,甚至不能使用整数)这是我的解决方案:
int heightaux(Node u) {
if(u == NULL) return -1;
int hLeft = 1 + heightaux(u->left);
int hRight = 1 + heightaux(u->right);
if(hLeft > hRight) return hLeft;
return hRight;
}
int height(Node u, int k) {
if(u == NULL) return 0;
int left = height(u->left, k);
int right = height(u->right, k);
return left + right + (heightaux(u) == k);
}
这里的时间复杂度是O(nlog(n)) 有没有办法优化这个?如果我可以编写一个使用空间复杂度 O(1) 的附加数据结构的算法,解决方案将如何变化?
二叉树示例:
5
1 9
6 10
k = 0 应该输出 3,因为节点 1、6 和 10 的高度 = 0
k = 1 应该输出 1,因为只有节点 9 的高度 = 1
k = 2 应该输出 1,因为只有节点 5 的高度 = 2
【问题讨论】:
-
您确定您正确解释了问题,尤其是“在树的给定高度”部分吗?您似乎将问题解释为“计算高度 k 的子树的数量”,这是一个公平的问题,但对于提出的约束,“计算深度 k 的节点数”(即距离根节点正好 k 步的节点数)似乎是一个更可能的问题。
-
说到约束,如果你不能使用额外的数据结构,甚至不能使用整数,那么提出的解决方案似乎是无效的。我在函数
height()中看到left和right,可以很容易地删除它们,在heightaux中看到hLeft和hRight,它们也可以删除,但不会牺牲一些效率。甚至有人可能会争辩说,辅助函数的参数违反了这一约束。 -
简单的 dfs 遍历应该是 O(n) 时间和 O(n) 空间(注意:由于递归将值存储在堆栈中,每次调用都会占用空间,因为在最坏的情况下,我们有高度不平衡的树 n 空间总是至少 O(n))
int dfs(node c, int h){return c == NULL ? 0 : !h + dfs(node.L, h-1) + dfs(node.R, h-1);}您的代码似乎在 O(n^2) 时间内计算大小为k的子树(二叉树不一定是平衡的) -
你还有其他关于树的信息吗?指定它是二进制似乎是一种浪费。 (即 complete?) 你怎么得到
O(n log n)? -
@Neil:N 叉树很难编写代码。
标签: c algorithm recursion binary-tree