找到树中间附近的所有节点

时间:2013-10-03 04:08:25

标签: algorithm data-structures tree

我从朋友的采访中得到了这个问题:给定一个二叉树,从树中间附近的所有级别打印节点数组(最多两个节点)。这是一个例子:
    

    1
/ \
2 3
/ \ \
4 5 9
/
10
输出为[ [2,3], [5,9], [10] ]。我只能想到一个效率低下的方法:对每个级别的树级别顺序,如果节点为NULL,则将当前级别的所有节点放入一个数组中,将一个标志(可能是-1或其他)放入插槽。最后,打印出每个数组中间的所有节点。
对于上面的例子,我的代码将首先得到4个数组:
[1], [2,3], [4,5,-1,9],[-1,-1,10,-1],在此过程之后,打印出所有中间数组中的值不是-1 我相信必须有更好的解决方案,任何人都能提供吗?谢谢!

3 个答案:

答案 0 :(得分:1)

我能想到这个问题的唯一方法是,从根本上说,我们可以将节点划分为两种类型:根的侧和侧的根。对于每个级别,对于左侧节点,我们找到最右侧节点,对于右侧,我们找到最左侧节点。希望这会对你有所帮助!

答案 1 :(得分:1)

按顺序遍历树并保持节点的级别

节点:4-2-5-1-3-10-9

等级:2-1-2-0-1-3-2

现在对于水平输出,我们从0级开始,找到左侧第一次出现1 - 对应的数字是2,找到右侧第一次出现1 - 对应的数字是3,所以1级输出是< 2,3>

为2级输出做同样的事情是< 5,9>

对于3级输出,

仅为< 10>

时间复杂度O(n) 空间复杂度O(n)

与级别订单遍历解决方案相同

答案 2 :(得分:0)

在我们遍历树的所有元素之前,我们永远无法确定元素是否存在于第i层。因此,时间复杂度永远不会比O(n)更好地优化,这与您提出的算法相同。

解决方案中唯一的问题是每个级别都需要维护一个单独的数组。虽然渐近地空间复杂性保持不变,但绝对数量却变得额外使用。

您可以做的是:

  1. 执行级别订单遍历。
  2. 对于每个元素,当您将其推送到队列时(对于水平顺序遍历),还要保持元素与中间的偏差。根将偏差为0.根的左子将具有-1。而正确的孩子将是+1。
  3. 对于每个级别,您需要保留一个“全局”元素,说明元素与中间的接近程度。对于给定级别,最多只能有2个元素。
  4. 为每个级别继续此操作。
  5. 对于稀疏树,此算法可以更好地实现空间复杂度。

    希望这有帮助!