题目描述

给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

[3,9,20,null,null,15,7]
    3
   / \
  9  20
    /  \
   15   7

返回锯齿形层次遍历如下:

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

算法

本题的算法和正常的层序遍历的区别就是正常的层序遍历使用的数据结构是队列,而本题使用的数据结构是栈

  • 将跟结点入栈
  • 然后将当前栈中所有的结点出栈
    • 如果下一层遍历的顺序是从右到左,那么当前出栈的每个结点的孩子结点入栈的顺序就是先左孩子后右孩子
    • 如果下一层遍历的顺序是从左到右,那么当前出栈的每个结点的孩子结点入栈的顺序就是先右孩子后左孩子
    • 孩子结点如果为空,那么这个孩子结点不入栈
  • 当栈为空的时候,整棵二叉树遍历完成

代码

func zigzagLevelOrder(root *TreeNode) [][]int {
	// 同时使用栈来解决二叉树层序遍历
	if root == nil {
		return [][]int{}
	}
	res := make([][]int, 0)
	queAndStk := []*TreeNode{root}
	flag := true
	for len(queAndStk) != 0 {
		tmpRes := make([]int, 0)
		tmpQS := make([]*TreeNode, 0)
		for index := len(queAndStk) - 1; index >= 0; index-- {
			tmpRes = append(tmpRes, queAndStk[index].Val)
			// 如果是从左向右
			if flag {
				if queAndStk[index].Left != nil {
					tmpQS = append(tmpQS, queAndStk[index].Left)
				}
				if queAndStk[index].Right != nil {
					tmpQS = append(tmpQS, queAndStk[index].Right)
				}
			} else {
				// 从右向左
				if queAndStk[index].Right != nil {
					tmpQS = append(tmpQS, queAndStk[index].Right)
				}
				if queAndStk[index].Left != nil {
					tmpQS = append(tmpQS, queAndStk[index].Left)
				}
			}
		}
		flag = !flag
		queAndStk = tmpQS
		res = append(res, tmpRes)
	}
	return res
}