leetcode 863. 二叉树中所有距离为 K 的结点 medium
题目描述:
给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 K 。
返回到目标结点 target 距离为 K 的所有结点的值的列表。 答案可以以任何顺序返回。
解题思路:
解法1: 把树转为图,简单来说,就是建一个hash表,保存每个节点的父节点,然后可以从target出发dfs 或者bfs
解法2: 爷自己想出来的哈,先找到从root到target经过的所有节点,然后根据这个路径查找所有可能的节点
代码:
//bfs
class Solution {
public:
vector<int> distanceK(TreeNode* root, TreeNode* target, int k) {
if(!root || !target || k<0)
return {};
unordered_map<TreeNode*,TreeNode*> parent;
setparent(root,root,parent);
//检查一下target在没在树上。
if(!parent.count(target))
return {};
// bfs
vector<int> res;
unordered_set<TreeNode*> visited{{target}};
queue<TreeNode*> que{{target}};
while(que.size()){
if(k==0){
for(int i=que.size();i>0;--i){
res.push_back(que.front()->val);
que.pop();
}
return res;
}
for(int i=que.size();i>0;--i){
TreeNode *cur=que.front();
que.pop();
if(cur->left && !visited.count(cur->left)){
que.push(cur->left);
visited.insert(cur->left);
}
if(cur->right && !visited.count(cur->right)){
que.push(cur->right);
visited.insert(cur->right);
}
if(!visited.count(parent[cur])){
que.push(parent[cur]);
visited.insert(parent[cur]);
}
}
--k;
}
return res;
}
//设置 子-》父节点 哈希表,根节点的父节点设为自己
void setparent(TreeNode* root,TreeNode *father,
unordered_map<TreeNode*,TreeNode*> &parent){
if(!root)
return;
parent[root]=father;
setparent(root->left,root,parent);
setparent(root->right,root,parent);
}
};
// dfs
class Solution {
public:
vector<int> distanceK(TreeNode* root, TreeNode* target, int k) {
if(!root || !target || k<0)
return {};
unordered_map<TreeNode*,TreeNode*> parent;
setparent(root,root,parent);
//检查一下target在没在树上。
if(!parent.count(target))
return {};
vector<int> res;
unordered_set<TreeNode*> visited;
dfs(target,k,visited,parent,res);
return res;
}
void dfs(TreeNode* cur,int k,unordered_set<TreeNode*> &visited,
unordered_map<TreeNode*,TreeNode*> &parent,vector<int> &res){
if(!cur || visited.count(cur) || k<0)
return;
if(k==0){
res.push_back(cur->val);
return;
}
visited.insert(cur);
dfs(cur->left,k-1,visited,parent,res);
dfs(cur->right,k-1,visited,parent,res);
dfs(parent[cur],k-1,visited,parent,res);
}
//设置 子-》父节点 哈希表,根节点的父节点设为自己
void setparent(TreeNode* root,TreeNode *father,
unordered_map<TreeNode*,TreeNode*> &parent){
if(!root)
return;
parent[root]=father;
setparent(root->left,root,parent);
setparent(root->right,root,parent);
}
};
//自己的解法,先找到找root到target经过的所有节点,然后根据这个路径查找所有可能的节点
//该实现 包括target没在树上的情况
class Solution {
public:
vector<int> distanceK(TreeNode* root, TreeNode* target, int k) {
if(!root || !target || k<0)
return {};
//找root到target经过的所有节点
vector<TreeNode*> path;
findpath(root,target,path);
if(path.empty())
return {};
vector<int> res;
for(int i=0;i<(int)path.size()-1;++i){
if((int)path.size()-1-i==k)
res.push_back(path[i]->val);
TreeNode *begin= path[i]->left==path[i+1]?path[i]->right:path[i]->left;
dfs(begin,0,k-(path.size()-i),res);
}
dfs(target,0,k,res);
return res;
}
bool findpath(TreeNode* root,TreeNode* target,vector<TreeNode*>& res){
if(root==nullptr)
return false;
res.push_back(root);
if(root==target){
return true;
}
if(findpath(root->left,target,res) || findpath(root->right,target,res))
return true;
else{
res.pop_back();
return false;
}
}
void dfs(TreeNode* root,int cur,int target,vector<int> &res){
if(root==nullptr)
return;
if(cur==target)
res.push_back(root->val);
else if(cur<target){
dfs(root->left,cur+1,target,res);
dfs(root->right,cur+1,target,res);
}
}
};