一、刷题内容
原题链接
https://leetcode-cn.com/problems/all-nodes-distance-k-in-binary-tree/
内容描述
给定一个二叉树(具有根结点 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
注意,输入的 “root” 和 “target” 实际上是树上的结点。
上面的输入仅仅是对这些对象进行了序列化描述。
提示:
给定的树是非空的。
树上的每个结点都具有唯一的值 0 <= node.val <= 500 。
目标结点 target 是树上的结点。
0 <= K <= 1000.
二、解题方法
对target节点距离为k的节点,我们可以分为三部分:
左子树上的点
右子树上的点
父节点上的点
对于 1 和 2 都很好解决,就是求深度差,但是对于 3 ,并不好求,因为父节点上还有父节点。
那么自然能想到,我们需要找出每个节点的父节点。如上图所示,也可以说这是一颗以target为根节点的多叉树,变成这样一种方式,显然能更加简单地求解。
使用dfs或者bfs都可以。
1.方法一:dfs
# dfs
class Solution:
def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]:
pres = {}
def helper(root, parent=None):
if not root:
return
pres[root] = parent
helper(root.left, root)
helper(root.right, root)
helper(root)
ans = []
def getDepth(root, parent=None, depth=0):
if not root:
return
if depth == k:
ans.append(root.val)
return
if root.left != parent:
getDepth(root.left, root, depth + 1)
if root.right != parent:
getDepth(root.right, root, depth + 1)
if pres[root] != parent:
getDepth(pres[root], root, depth + 1)
getDepth(target)
return ans
2.方法二:bfs
# bfs
class Solution:
def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]:
pres = {}
def helper(root, parent=None):
if not root:
return
pres[root] = parent
helper(root.left, root)
helper(root.right, root)
helper(root)
ans = []
q = deque()
q.append((target, 0))
seen = set()
while q:
cur, depth = q.popleft()
if not cur:
continue
if depth == k and cur:
ans.append(cur.val)
if cur in seen:
continue
seen.add(cur)
if cur.left and cur.left not in seen:
q.append((cur.left, depth + 1))
if cur.right and cur.right not in seen:
q.append((cur.right, depth + 1))
if cur in pres and pres[cur] not in seen:
q.append((pres[cur], depth + 1))
return ans