SWE · Stage 1 Technical Question

Oracle 二叉树 Bottom View:水平距离与同深并列

把二叉树节点映射到水平列,按深度决定底部可见节点,并明确同深同列的训练并列规则。

题目重点:把二叉树节点映射到水平列,按深度决定底部可见节点,并明确同深同列的训练并列规则。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 根列为 0,左子节点列减 1,右子节点列加 1;深度从根 0 开始。输出按列从小到大。
  • 同列同深时,训练代码取 BFS 左到右遍历中较晚访问的节点;其他平台可能有不同 tie-break,应先询问。

解题路线

  1. BFS 队列携带 (node,column,depth),每取一节点,用该列现有记录与当前深度比较,较深者覆盖。
  2. 同深时按训练并列规则让后访问者覆盖。BFS 先左后右入队,队列在同一深度保持从左到右的顺序。
  3. 遍历结束后按 column 排序并输出保留的值;如果列跨度受 N 限制,也可维护 min/max column 顺次读出。
  4. 每列保留的深度不小于该列已访问所有节点,因此扫描完成时就是底部节点;同深规则保证结果确定。

手动走一遍

根 1,左子 2、右子 3;2 的右子 4 与 3 的左子 5 都在列 0、深度 2。按训练规则 BFS 后到的 5 覆盖 4,列 -1/0/1 的结果为 [2,5,3]。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

"""Bottom view with later BFS order winning equal-depth ties."""

from collections import deque


class TreeNode:
    def __init__(self, value: int, left: "TreeNode | None" = None, right: "TreeNode | None" = None):
        self.value = value
        self.left = left
        self.right = right


def bottom_view(root: TreeNode | None) -> list[int]:
    if root is None:
        return []
    queue = deque([(root, 0, 0)])
    seen: dict[int, tuple[int, int]] = {}
    while queue:
        node, column, depth = queue.popleft()
        previous = seen.get(column)
        if previous is None or depth >= previous[0]:
            seen[column] = (depth, node.value)
        if node.left is not None:
            queue.append((node.left, column - 1, depth + 1))
        if node.right is not None:
            queue.append((node.right, column + 1, depth + 1))
    return [seen[column][1] for column in sorted(seen)]

复杂度

N 个节点遍历 O(N),对至多 N 个列排序 O(C log C),空间 O(W+C),W 为 BFS 最大层宽。若用有序映射,时间可 O(N log C)。

易错点与追问

容易失分的边界

  • 只保留每列最后访问节点,却未说明遍历顺序或深度;DFS 的最后访问不一定是最深。
  • 把 top view 的最浅节点规则误用于 bottom view。
  • 同深同列不问并列规则,导致与测试平台期望不一致。

继续深挖

  • 若要求同深时优先更左的节点,比较条件如何改?
  • vertical order traversal 与 bottom view 的输出语义有何不同?
✓已复制微信号!