广度优先遍历算法思想

对比:DFS VS. BFS

  • DFS:侧重点,分支
  • BFS:侧重点,层

如果遇到可以用 DFS 解决的题目,尝试也可以使用 BFS 解决

BFS 常用工具:

队列:先进先出

  • queue.push() 入队
  • queue.shift() 出队

推荐练习题:

  • 102 二叉树的层序遍历
  • 104 二叉树的最大深度
  • 200 岛屿数量

题型一

难度中等

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

示例: 二叉树:[3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其层序遍历结果:

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

通过次数272,234

提交次数423,926


/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
    let result = []

    if (!root) return result

    const queue = []
    queue.push(root)
    // 开启一个新的层级
    while(queue.length) {
        let length = queue.length
        let list = []
        // 开启遍历当层元素的循环
        while(length) {
            let cur = queue.shift()
            if (cur.val !== null) list.push(cur.val)

            if (cur.left !== null) queue.push(cur.left)
            if (cur.right !== null) queue.push(cur.right)

            length -= 1
        }

        result.push(list.concat([]))
    }
    return result
};
  • 使用 DFS

核心:利用 层级 进行处理,每一个层级就是一个子数组,往里面插入当层的元素

Code:

 var levelOrder = function(root) {
     let result = []
     if (root === null) return result
    
     dfs(root, result, 0)
     return result
 }

 function dfs(node, result, level) {

     // 返回终止条件
     if (node === null) return
     // 若当前 level 是 1,那么对应层级是 1,result 应该有(length) 2 个子数组。若 小于,则说明需要加一个子数组
     if (level > result.length - 1) result.push([])

     result[level].push(node.val)


     if (node.left !== null) {
         dfs(node.left, result, level + 1)
     }

     if (node.right !== null) {
        dfs(node.right, result, level + 1)
     }
 }

难度中等422

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

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

    3
   / \
  9  20
    /  \
   15   7

返回其自底向上的层序遍历为:

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

视频:https://www.bilibili.com/video/BV1sy4y1q79M?p=72

题解:https://mp.weixin.qq.com/s/NjQfu0asTnhtxs7R7HnYgA

说明:和 102 题类似,方法倒置即可

解法一:使用链表 + BFS 解

技巧:因为 链表可以快速 插入,时间复杂度 O(1),如果使用 数组,则时间复杂度为 O(n)

Code:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */

// 以下部分为伪代码
var levelOrderBottom = function(root) {
    let result = []

    if (root === null) return result
	
    // 定义空链表
    let temp = new ListNode()
    
    let que = []
    que.push(root)

    while(que.length) {
        let len = que.length

        let list = []

        while(len > 0) {
            let cur  = que.shift()

            list.push(cur.val)

            if (cur.left !== null ) que.push(cur.left)

            if (cur.right !== null ) que.push(cur.right)

            len -= 1

        }
        // 头插法
        temp.addFirst(list.concat([]))
    }
	// 将 链表转换成线性表
    result = list(temp)
    return result
};

实际为:

Code:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrderBottom = function(root) {
    let result = []

    if (root === null) return result

    let que = []
    que.push(root)

    while(que.length) {
        let len = que.length

        let list = []

        while(len > 0) {
            let cur  = que.shift()

            list.push(cur.val)

            if (cur.left !== null ) que.push(cur.left)

            if (cur.right !== null ) que.push(cur.right)

            len -= 1

        }
        result.unshift(list.concat([]))
    }

    return result
};
  • DFS + reverse

Code:

var levelOrderBottom = function(root) {
    let result = []
    if (root === null) return result
    dfs(root, result, 0)
    return result.reverse()
}


function dfs(node, result, level) {
    if (node === null) return

    if (level > result.length -1) {
        result.push([])
    } 

    result[level].push(node.val)

    if (node.left !== null) {
        dfs(node.left, result, level +1)
    }

    if (node.right !== null) {
        dfs(node.right, result, level + 1)
    }
}