返回二叉树的锯齿形层序遍历:第一层从左到右,第二层从右到左,之后交替方向。
节点的访问顺序仍然是标准 BFS。变化的只是每层结果的写入方向。
也就是说,队列仍然负责按层、从左到右访问节点;锯齿形只影响当前层结果数组的写入位置。不要为了反向输出而改变孩子的入队顺序,否则容易破坏下一层的正常结构。
使用 leftToRight 表示当前层方向。每层创建一个长度为 levelSize 的数组:
i。levelSize - 1 - i。这样既不需要反转数组,也不需要在数组头部插入元素。
levelSize - 1 是当前层数组的最后一个下标。levelSize - 1 - i 表示从最后一个位置开始写,随着 i 增大,写入位置一步步向左移动。
例如当前层按 BFS 访问到的节点是 [9, 20],levelSize = 2。
关键点是:访问顺序不变,写入位置改变。
时间复杂度:O(n),每个节点只会被访问一次。
空间复杂度:O(n)。
当前实现使用 head 指针模拟出队,queue 中访问过的节点不会被删除,最坏情况下会保存所有节点。如果使用真正的队列结构,只看遍历过程中的待处理节点,辅助空间可以理解为 O(w),其中 w 是二叉树最大层宽。计入返回结果时一定是 O(n)。
[]。unshift() 会反复移动数组元素,宽层情况下效率较差。leftToRight 要在每一层结束后切换,不能在处理每个节点时切换。head 指针时,循环条件应该是 head < queue.length,不能只判断 queue.length > 0。