❝原题地址:https://leetcode-cn.com/problems/binary-tree-vertical-order-traversal/
❞
原文链接:https://juejin.cn/post/6873108574982111239
题目
给定一个二叉树,返回其结点 垂直方向(从上到下,逐列)遍历的值。
如果两个结点在同一行和列,那么顺序则为 从左到右。
示例 1:
输入: [3,9,20,null,null,15,7]
3
/\
/ \
9 20
/\
/ \
15 7
输出:
[
[9],
[3,15],
[20],
[7]
]
示例 2:
输入: [3,9,8,4,0,1,7]
3
/\
/ \
9 8
/\ /\
/ \ / \
4 0 1 7
输出:
[
[4],
[9],
[3,0,1],
[8],
[7]
]
示例 3:
输入: [3,9,8,4,0,1,7,null,null,null,2,5](注意:0 的右侧子节点为 2,1 的左侧子节点为 5)
3
/\
/ \
9 8
/\ /\
/ \/ \
4 01 7
/\
/ \
5 2
输出:
[
[4],
[9,5],
[3,0,1],
[8,2],
[7]
]
解题思路
深度优先搜索
对于一棵二叉树,它的垂序遍历结果是从上到下,从左到右的。
因此,我们可以以根节点为起点,利用 index
来标记每个节点的顺序,对于不同深度的节点,我们则用 depth
来标记,之后直接排序即可。
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
const verticalOrder = function(root) {
/**
* @param {TreeNode} root
* @param {number} index
* @param {number} depth
*/
const helper = (root, index, depth) => {
if (!root) {
return
}
const { val, left, right } = root
min = Math.min(min, index)
max = Math.max(max, index)
if (cache.has(index)) {
cache.get(index).push({ depth, val })
} else {
cache.set(index, [{ depth, val }])
}
helper(left, index - 1, depth + 1)
helper(right, index + 1, depth + 1)
}
if (!root) {
return []
}
const cache = new Map()
const res = []
let min = 0
let max = 0
helper(root, 0, 0)
for (let i = min; i <= max; i++) {
const nums = cache.get(i).sort((a, b) => a.depth - b.depth).map((item) => item.val)
res.push(nums)
}
return res
}
广度优先搜索
前面提到的「深度优先搜索」的解法需要对数组内的元素按深度进行排序,为什么呢? 因为「深度优先搜索」是以「深度」为第一优先级的,所以可能存在同一列的值在最底层的值先被存入数组,导致结果出错。 相反,如果我们用 「广度优先搜索」 一层层的遍历,就可以保证同一列值里的顺序是没问题的。
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
const verticalOrder = function(root) {
if (!root) {
return []
}
const res = []
const cache = new Map()
const queue = [{ root, index: 0 }]
let min = 0
let max = 0
while (queue.length) {
let loop = queue.length
while (loop--) {
const { root, index } = queue.shift()
min = Math.min(min, index)
max = Math.max(max, index)
if (root.left) {
queue.push({ root: root.left, index: index - 1 })
}
if (root.right) {
queue.push({ root: root.right, index: index + 1 })
}
if (cache.has(index)) {
cache.get(index).push(root.val)
} else {
cache.set(index, [root.val])
}
}
}
for (let i = min; i <= max; i++) {
res.push(cache.get(i))
}
return res
}
关注我的微信公众号「tony老师的前端补习班」,即可获得最新文章~