剑指 Offer 32 - III. 从上到下打印二叉树 III

100 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

剑指 Offer 32 - III. 从上到下打印二叉树 III

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
/ \   9  20
/  \    15   7
返回其层次遍历结果:

[
[3],
[20,9],
[15,7]
]

提示:

节点总数 <= 1000

思路: 

  • 在 剑指 Offer 32 - II. 从上到下打印二叉树 II 的基础上,要求按照之字形顺序打印二叉树,即:第1行(从左往右) -> 第2行(行从右往左 )-> 第3行(从左往右)...
  • 那么可以提前构造好subRes数组,初始化时指定其大小,用于下标操作
  • 通过isReverse标志位来控制每行打印时的左右来回变换
  • 从左往右:subRes[i] = root.Val;   从右往左:subRes[size - i - 1] = root.Val

时间复杂度: O(N),N 为二叉树的节点数量,即 BFS 需循环 N 次。

空间复杂度: O(N),使用O(N) 大小的额外空间。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func levelOrder(root *TreeNode) [][]int {
    res := make([][]int, 0)
	if root == nil {
		return res
	}

	queue := make([]*TreeNode, 0)
	queue = append(queue, root) // 开始循环前,先塞入root
	var isReverse bool = true // 每一轮外循环后都置换一次:左右->右左...

	for len(queue) > 0 {
		size := len(queue) // for循环必须使用外层循环保存的size,不能直接使用len(queue),因为内循环中的queue是会append操作的,会导致len(queue)的长度不断变化
        subRes := make([]int, size) // 注意:提前分配好size大小,用于操作下标
		for i := 0; i < size; i++ {
			root = queue[0]   // 获取即将出队的头节点
            if isReverse == true {
                subRes[i] = root.Val // 从左往右
            } else {
                subRes[size - i - 1] = root.Val // 从右往左
            }
			
			queue = queue[1:] // 头结点出队

			if root.Left != nil {
                queue = append(queue, root.Left)
            }

            if root.Right != nil {
                queue = append(queue, root.Right)
            }
		}
		res = append(res, subRes)
		isReverse = !isReverse
	}

	return res
}

建议按顺序做此三道题:

剑指 Offer 32 - I. 从上到下打印二叉树              本题额外要求:BFS

剑指 Offer 32 - II. 从上到下打印二叉树 II          本题额外要求:每一层打印到一行

剑指 Offer 32 - III. 从上到下打印二叉树 III        本题额外要求:打印顺序交替变化