LeetCode二叉树层次遍历套路

102. 二叉树的层次遍历

题目来源:
https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
难易程度:中等

题目描述

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。

例如:
给定二叉树: [3,9,20,null,null,15,7],
第一层:3
第二层: 9 20
第三层: 15 7
返回其层次遍历结果:

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

算法实现

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func levelOrder(root *TreeNode) [][]int {
    var res [][]int
    if(root == nil) {
        return res
    }
    var nextLevelNodes []*TreeNode                  // 层次节点队列,存放各层节点
    nextLevelNodes = append(nextLevelNodes, root)   // 根不为空,则先将根加入层次节点队列
    for len(nextLevelNodes) > 0 {
        var levelVals []int                         // 存放当前层次遍历到的节点
        levelNums := len(nextLevelNodes)            // 当前层次节点数
        
        for i := 0; i < levelNums; i++ {
            curNode := nextLevelNodes[0]                // 每次从当前层次队列中取出队头节点进行遍历
            levelVals = append(levelVals, curNode.Val)  // 把当前遍历到的节点的值加入到层次节点值的队列中
            nextLevelNodes = nextLevelNodes[1:]         // 把遍历过的节点从层次节点队列中删除
            if(curNode.Left != nil) {                   // 当前节点的左孩子非空,就添加到层次节点队列中
                nextLevelNodes = append(nextLevelNodes, curNode.Left)
            }
            if(curNode.Right != nil) {                  // 当前节点的右孩子非空,就添加到层次节点队列中
                nextLevelNodes = append(nextLevelNodes, curNode.Right)
            }
        }
        res = append(res, levelVals)                    // 当前层次所有节点遍历完,就将节点值队列添加到结果切片中
    }
    return res
}

LeetCode 107. 二叉树的层次遍历 II

题目来源:
https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/
难易程度:简单

题目描述

给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

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

第一层: 3
第二层:9 20
第三层:15 7
返回其自底向上的层次遍历为:

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

算法实现

下面的算法时间复杂度: O(n), 空间复杂度: O(n)

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

// 先从根到叶子进行层次遍历,然后对遍历的结果进行前后翻转
func levelOrderBottom(root *TreeNode) [][]int {
    res := levelOrder(root)
    
    // 正序结果翻转
    for i := 0; i < len(res)/2; i++ {
        j := len(res) - 1 - i
        res[i], res[j] = res[j], res[i]
    }
    return res
}

// 按照从根到叶子的方向的层次遍历
func levelOrder(root *TreeNode) [][]int {
    if(root == nil) {
        return nil
    }

    var curLevelNodes []*TreeNode                   // 存放当前遍历层次的所有节点
    var res [][]int                                 // 存放从根到叶子的各层次的节点的值
    curLevelNodes = append(curLevelNodes, root)     // 根节点入队列
    for len(curLevelNodes) > 0 {
        var curLevelVal []int                // 存放当前层次节点的值
        size := len(curLevelNodes)
        for i := 0; i < size; i++ {          // 注意:这里的size不能直接替换为curLevelNodes,因为这个for循环中有改变队列curLevelNodes的行为
            curNode := curLevelNodes[0]                     // 取出队头节点遍历并从队列中删除
            curLevelNodes = curLevelNodes[1:]
            curLevelVal = append(curLevelVal, curNode.Val)  // 将当前遍历的节点的值加入层次节点值队列
            if(curNode.Left != nil) {                       // 将当前节点的左右子节点加入层次节点队列
                curLevelNodes = append(curLevelNodes, curNode.Left)
            }
            if(curNode.Right != nil) {
                curLevelNodes = append(curLevelNodes, curNode.Right)
            }
        }
        res = append(res, curLevelVal)
    }
    return res
}

LeetCode 637. 二叉树的层平均值

题目来源:
https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/
难易程度:容易

题目描述

给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.

示例 1:

输入:
第一层:3
第二层: 9 20
第三层: 15 7
输出: [3, 14.5, 11]
解释:
第0层的平均值是 3, 第1层是 14.5, 第2层是 11. 因此返回 [3, 14.5, 11].
注意:

节点值的范围在32位有符号整数范围内。

算法实现

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func averageOfLevels(root *TreeNode) []float64 {
    levelArr := levelOrder(root)
    var res []float64
    for i := 0; i < len(levelArr); i++ {
        var sum float64         // 每次计算各个子切片是和清零
        for j := 0; j < len(levelArr[i]); j++ {
            sum += float64(levelArr[i][j])
        }
        res = append(res, sum / float64(len(levelArr[i])))   // 计算每个子切片的平均值并添加到结果队列中
    }
    return res
}

// 从根到叶子节点进行层次遍历    
func levelOrder(root *TreeNode) [][]int {
    var res [][]int
    if(root == nil) {
        return res
    }
    var nextLevelNodes []*TreeNode                  // 依次存放每一层的节点
    nextLevelNodes = append(nextLevelNodes, root)   // 先将根节点放入进来
    for len(nextLevelNodes) > 0 {                   // 当前层次的节点没有遍历完,就一直循环遍历
        var levelVals []int                         // 存放每层节点的值
        levelNodeNum := len(nextLevelNodes)         // 当前层次需要遍历的节点数
        for i := 0; i < levelNodeNum; i++ {         // 依次从队列中对当前层的节点逐个遍历
            curNode := nextLevelNodes[0]            // 从层次队列中依次(从队头)取节点进行遍历
            levelVals = append(levelVals, curNode.Val)  // 将当前节点的值放入节点值的层次队列
            nextLevelNodes = nextLevelNodes[1:]     // 遍历后删除该节点
            if(curNode.Left != nil) {               // 当前节点的左孩子非空,就加入下一层的层次节点
                nextLevelNodes = append(nextLevelNodes, curNode.Left)
            }
            if(curNode.Right != nil) {
                nextLevelNodes = append(nextLevelNodes, curNode.Right)
            }
        }
        res = append(res, levelVals)                // 每遍历完一层,就将该层的节点值队列加入结果层次数组中
    }
    return res
}

你可能感兴趣的:(算法,LeetCode,数据结构,二叉树)