You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现BST右视图时两种for循环写法结果差异原因咨询

二叉树右视图BFS实现两种for循环写法的差异原因

可正常运行的正确实现

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []

        result = []
        
        q = []
        q.append(root)
        
        while len(q):
            # 关键差异行
            for _ in range(len(q)):
                node = q.pop(0)
                if node.left != None:
                    q.append(node.left)
                    
                if node.right != None:
                    q.append(node.right)
            result.append(node.val)
        
        return result

该实现针对测试用例root = [1,2,3,null,5,null,4]可输出正确结果[1,3,4]。

存在问题的错误实现

仅将循环行替换为直接遍历队列for _ in (q):,其余逻辑不变:

def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []

        result = []
        
        q = []
        q.append(root)
        
        while len(q):
            # 改动后的差异行
            for _ in (q):
                node = q.pop(0)
                if node.left != None:
                    q.append(node.left)
                    
                if node.right != None:
                    q.append(node.right)
            result.append(node.val)
        
        return result

相同测试用例下该实现输出错误结果[2,5,4]。

差异核心原理

两种写法的本质区别是for循环的迭代边界是否在启动时固定:

  • for _ in range(len(q))的逻辑:
    range()函数会在for循环启动的瞬间,读取当时队列的长度值,生成一个固定长度的整数迭代序列。后续循环过程中不管怎么对队列做pop出队、append入队操作,循环的执行次数都和刚进入循环时的队列长度完全一致,刚好把当前层的所有节点处理完,不会触碰循环中新加入的下一层节点,完全符合BFS层序遍历按层分割的要求。每次内层for循环结束时,最后一个被pop的节点就是当前层最右侧的节点,将其值加入结果集即可得到正确的右视图。
  • for _ in q的逻辑:
    Python中直接遍历列表时,迭代器会动态跟踪列表的长度和元素位置:从索引0开始逐位取元素,每取完一个元素索引自增,直到索引超出列表当前实时长度才会停止遍历。
    你在内层循环中持续执行pop(0)移除队首元素,又持续将子节点追加到队尾,队列的长度、元素位置在整个循环过程中一直动态变化,迭代器会遍历到所有循环过程中新加入的元素,完全打破了「每次内层循环只处理一层节点」的边界。内层for循环结束时拿到的最后一个node根本不是当前层的最右节点,自然会输出错误结果。

初始阶段流程示例:初始队列q=[1]进入while循环,启动对q的遍历,第一次迭代取出节点1,将其左右孩子2、3加入队列,此时q变为[2,3];迭代器不会因为初始q只有1个元素就停止,会继续取当前q的下一位元素,持续处理后续新加入的节点,完全跨层执行,最终第一层for循环结束时最后留存的node值为2,被错误加入结果集,后续逻辑也全部错位。


内容的提问来源于stack exchange,提问作者young_coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:54:27