SWE · Coding

Meta Binary Tree Paths:进入/退出事件与输出成本

返回所有根到叶的路径字符串,使用共享当前路径和迭代回溯避免每节点复制。

题目重点:返回所有根到叶的路径字符串,使用共享当前路径和迭代回溯避免每节点复制。

题意与假设

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

  • 训练Node.value可转字符串,路径分隔符→在代码为ASCII ->,叶子无左右孩子;按左到右叶顺序返回,空树[]。
  • 不是返回各路径和,非叶中间节点不形成完整输出。

解题路线

  1. 栈存(node,exitFlag)。进入时把value加入path并安排退出,先压right再left保证左先遍历。退出时pop当前值,恢复父路径。
  2. 只有左右都None才join当前path输出;单边节点不是叶,不提前输出。共享path避免把长路径list复制给每个child。
  3. exit事件确保遍历兄弟前清掉前一子树节点,否则路径会串上无关支路。输出字符串在叶子时独立创建,后续path变更不会改结果。
  4. 可递归DFS append/pop实现同样逻辑;迭代版本免递归深度限制,但仍需栈保存沿途与待处理分支。独立oracle沿每叶parent回走到root验证。

手动走一遍

根1左2且2右5,根右3,输出1->2->5、1->3。若2只有右5,不能将1->2也输出;空树没有空路径。

Python 参考实现

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

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

def root_leaf_paths(root):
    """Left-to-right leaf order, '->' text, empty tree []; stringifiable values."""
    if root is None:return []
    result=[];path=[];stack=[(root,False)]
    while stack:
        node,exit=stack.pop()
        if exit:path.pop();continue
        path.append(str(node.value));stack.append((node,True))
        if node.left is None and node.right is None:result.append('->'.join(path))
        else:
            if node.right is not None:stack.append((node.right,False))
            if node.left is not None:stack.append((node.left,False))
    return result

复杂度

遍历O(N),加输出总字符数S,时间O(N+S),辅助O(h)栈/当前path,输出O(S)。每叶都复制字符串是输出必需成本,不能把大量长路径说成整体O(N)。

易错点与追问

容易失分的边界

  • 任一child缺失就当leaf,单边树截断。
  • 保存同一个可变path引用到结果,后续pop会清空所有结果。

继续深挖

  • 如果返回value数组而非字符串,输出空间按总路径节点数计算。
  • 需要迭代器逐叶yield时,如何在yield后恢复path且不暴露可变引用?
✓已复制微信号!