给定一个二叉树,返回其节点值自底向上的层序遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
例如:
给定二叉树[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
};