「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」
863. 二叉树中所有距离为 K 的结点
给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 k 。
返回到目标结点 target 距离为 k 的所有结点的值的列表。 答案可以以 任何顺序 返回
示例1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2
输出:[7,4,1]
解释:所求结点为与目标结点(值为 5)距离为 2 的结点,值分别为 7,4,以及 1
示例2:
输入: root = [1], target = 1, k = 3
输出: []
提示:
- 节点数在 [1, 500] 范围内
- 0 <= Node.val <= 500
- Node.val 中所有值 不同
- 目标结点 target 是树上的结点。
- 0 <= k <= 1000
从目标节点上下递归
思路 由题意可知,给定我们一棵二叉树,并且指定了一个目标节点
如示例1中的target为5,并不是说target是数字5,而是说target是值为5的这个节点,是一个对象。
接着给了一个范围k,收集所有距离traget为k的值,距离我们可以理解为两节点之间相连的线,两个节点之间为1,因此就是数k条线对应的那个节点的值
这里我们从目标节点target出发,向上和向下查找
具体实现:
- 首先深度优先遍历整个二叉树,同时处理所有节点,给他们一个prev 指向他们的父节点
- 处理完毕声明两个查找函数
- 向下查找每次判断当前距离n是否等于k,等于则结束递归,否则递归查找left和right子节点,同时n+1
- 向上查找,就是从prev开始找,找到目标节点后还要继续递归爷爷节点,以及父节点的另外一个子节点,距离n+1
- 当n===k时将当前节点root存放到res中
最后返回res即可
var distanceK = function (root, target, k) {
var stack = [root]
var res = []
while (stack.length) {
var item = stack.pop()
// 处理左右
var left = item.left
var right = item.right
if (left) {
left.prev = item
stack.push(left)
}
if (right) {
right.prev = item
stack.push(right)
}
}
// 向下查找
function findDown(root, n) {
if (!root) return
if (n === k) {
res.push(root.val)
return
}
findDown(root.left, n + 1)
findDown(root.right, n + 1)
}
// 向上查找
function findUp(root, n, prev) {
if (!root) return
if (n === k) {
res.push(root.val)
return
}
if (n > k) return
// 向下
if (root.left && root.left.val === prev) {
findDown(root.right, n + 1)
}
if (root.right && root.right.val === prev) {
findDown(root.left, n + 1)
}
// 向上
findUp(root.prev, n + 1, root.val)
}
// 处理起点
if (k === 0) {
return [target.val]
} else {
// 向下查找
findDown(target.left, 1)
findDown(target.right, 1)
// 向上查找
findUp(target.prev, 1, target.val)
}
return res
};