【树】B051_LC_二叉树中所有距离为 K 的结点(广搜 + 深搜存储父节点)
程序员文章站
2023-12-27 14:08:09
...
一、Problem
给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 K 。
返回到目标结点 target 距离为 K 的所有结点的值的列表。 答案可以以任何顺序返回。
输入: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.
二、Solution
方法一:bfs + dfs
思路
由于 tar 结点不一定是整棵树的 root,距离为 K 的结点可能在其它子树上,所以我们需要将某个结点 node 的父亲给链接起来,于是我们利用 dfs 找到所有结点的父亲
再用 bfs 从 tar 结点开始向左子树、右子树、父亲三个方向遍历 K 次,遍历次数达到第 K 次时,队列中的结点到 tar 结点的距离就是 K
class Solution {
public:
unordered_map<TreeNode*, TreeNode*> pars;
void dfs(TreeNode* node, TreeNode* par) {
if (node == NULL) return;
pars[node] = par;
dfs(node->left, node);
dfs(node->right, node);
}
vector<int> distanceK(TreeNode* root, TreeNode* tar, int K) {
dfs(root, NULL);
queue<TreeNode*> q;
unordered_map<TreeNode*, bool> vis;
q.push(tar);
vis[tar] = true;
while (!q.empty()) {
if (K-- == 0) {
vector<int> ans;
while (!q.empty()) ans.push_back(q.front()->val), q.pop();
return ans;
} else {
int sz = q.size();
for (int i = 0; i < sz; i++) {
auto cur = q.front(); q.pop();
if (cur->left != NULL && !vis[cur->left])
q.push(cur->left), vis[cur->left] = true;
if (cur->right != NULL && !vis[cur->right])
q.push(cur->right), vis[cur->right] = true;
if (pars[cur] != NULL && !vis[pars[cur]])
q.push(pars[cur]), vis[pars[cur]] = true;
}
}
}
return {};
}
};
复杂度分析
- 时间复杂度:,
- 空间复杂度: