[路飞]_前端算法第六十三弹-二叉树的层序遍历 II

96 阅读2分钟

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

例如:

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

		3
   / \\
  9  20
    /  \\
   15   7

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

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

这道题和「 二叉树的层序遍历」相似,不同之处在于,「 二叉树的层序遍历」求从上到下输出每一层的节点值,而这道题要求从下到上输出每一层的节点值。除了输出顺序不同以外,这两道题的思路是相同的,都可以使用广度优先搜索进行层次遍历。

深度优先搜索

这道题只需要将「 二叉树的层序遍历」的值进行倒叙输出即可

利用unshift()性质,每次最新获得的值都放置于该层的最前端。

var levelOrderBottom = function (root) {
    let ans = [];
    getResult(root, 0, ans)
    return ans
    function getResult(root, k, ans = []) {
        if (!root) return [];
        if (k == ans.length) ans.unshift([]);
        ans[ans.length - 1 - k].push(root.val);
        getResult(root.left, k + 1, ans)
        getResult(root.right, k + 1, ans)
    }
};

广度优先搜索

树的层次遍历可以使用广度优先搜索实现。从根节点开始搜索,每次遍历同一层的全部节点,使用一个列表存储该层的节点值。

如果要求从上到下输出每一层的节点值,做法是很直观的,在遍历完一层节点之后,将存储该层节点值的列表添加到结果列表的尾部。这道题要求从下到上输出每一层的节点值,只要对上述操作稍作修改即可:在遍历完一层节点之后,将存储该层节点值的列表添加到结果列表的头部。

为了降低在结果列表的头部添加一层节点值的列表的时间复杂度,结果列表可以使用链表的结构。

var levelOrderBottom = function (root) {
    let res = [];
    if (!root) return res;
    let queue = [];
    queue.push(root);
    while (queue.length) {
        let temp = [];
        let len = queue.length;
        for (let i = 0; i < len; i++) {
            let node = queue.shift();
            temp.push(node.val);
            let left = node.left, right = node.right;
            left && queue.push(left);
            right && queue.push(right);
        }
        res.unshift(temp)
    }
    return res
};