该题链接点击这里:
给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 K 。
返回到目标结点 target 距离为 K 的所有结点的值的列表。 答案可以以任何顺序返回。
看到要求我们返回所有离某节点距离为k的节点,我们应该想到使用广度优先搜索,向外迈出k步,然后得到我们需要的节点。这基本上属于一道中规中矩的模板题,技巧点可能在于图的建立。
一般情况下我们可以通过情况来判断该如何建立图的模型,这里,考虑到从二叉树来构造图,会带来坐标难以表示的问题,我们选用邻接表结构进行建图。
题目中给我们了二叉树节点的定义:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
我们根据定义建立邻接链表即可,为了方便,我们使用map数据结构,结合vector或list来完成图的表示:(这里使用vector)
unordered_map<TreeNode*, vector<TreeNode*>>mp;
解释:key为每一个节点,vector中存有与key相邻的每一个节点。
接着,我们使用树的前序遍历来完成建图过程:
由于每个节点与父节点,左右节点相邻,所以我们做三次判断,若相邻节点不为空,就加入邻接表:
/*
root为当前节点 father为父节点
前序遍历就可建图
初始化时传入整棵树的根节点 此时father参数为nullptr
*/
void dfs(TreeNode* root,TreeNode* father){
if(!root)return;
if(father)mp[root].push_back(father);
if(root->left)mp[root].push_back(root->left);
if(root->right)mp[root].push_back(root->right);
dfs(root->left, root);
dfs(root->right, root);
}
我们使用set判断是否遍历到当前节点:
unordered_set<TreeNode*>s;
定义bfs函数,返回距离target节点步长为k的节点队列:
queue<TreeNode*>bfs(TreeNode* target,int k){
queue<TreeNode*>q;
q.push(target);
//s为集合 保证只遍历每个元素一次 初始化时讲target加入
s.insert(target);
for(int i=0;i<k;i++){
//向外走k步
int n=q.size();
//当前队列中的节点全都向外走一步
for(int j=0;j<n;j++){
TreeNode* cur=q.front();
q.pop();
for(auto next:mp[cur]){
//如果当前节点的邻接节点没有遍历 就遍历
if(!s.count(next)){
q.push(next);
s.insert(next);
}
}
}
}
return q;
}
这样我们就得到了结果。
完整的代码段如下(leetcode核心代码模式下,无输入输出):
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
unordered_map<TreeNode*, vector<TreeNode*>>mp;
unordered_set<TreeNode*>s;
void dfs(TreeNode* root,TreeNode* father){
if(!root)return;
if(father)mp[root].push_back(father);
if(root->left)mp[root].push_back(root->left);
if(root->right)mp[root].push_back(root->right);
dfs(root->left, root);
dfs(root->right, root);
}
vector<int> distanceK(TreeNode* root, TreeNode* target, int k) {
dfs(root, nullptr);
queue<TreeNode*>q=bfs(target,k);
vector<int>ans;
while(!q.empty()){
ans.push_back(q.front()->val);
q.pop();
}
return ans;
}
queue<TreeNode*>bfs(TreeNode* target,int k){
queue<TreeNode*>q;
q.push(target);
s.insert(target);
for(int i=0;i<k;i++){
int n=q.size();
for(int j=0;j<n;j++){
TreeNode* cur=q.front();
q.pop();
for(auto next:mp[cur]){
if(!s.count(next)){
q.push(next);
s.insert(next);
}
}
}
}
return q;
}
};
希望这篇文章对你有帮助。