广度优先遍历算法思想
对比: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
- 视频:https://www.bilibili.com/video/BV1sy4y1q79M?p=71&spm_id_from=pageDriver
 - 题解:https://mp.weixin.qq.com/s/aYvJ3cBSBhtrcsiOsUjLyA
 - 方法:
 - 使用 BFS
 
/**
 * 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)
    }
}