思路:主要就是用DFS做当前节点和父节点的映射,这样就能在target节点BFS的形式处发散出去;其次,为了防止发散过程中重复遍历某个节点,设定set或者map,对里面已存放的节点不加遍历;有时候做题不要想多厉害的方法,踏踏实实的这种反而挺有效!
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
//parent存放当前节点的父节点
map<TreeNode *, TreeNode *> parent;
//遍历树,把每个节点 <节点,父节点> 存入parent
void dfs(TreeNode *cur, TreeNode *par)
{
parent[cur] = par;
if (cur->left)
dfs(cur->left, cur);
if (cur->right)
dfs(cur->right, cur);
}
vector<int> distanceK(TreeNode *root, TreeNode *target, int K)
{
vector<int> res;
if (!root)
{
return res;
}
if (K == 0)
{
res.push_back(target->val);
return res;
}
dfs(root, NULL);
queue<TreeNode *> q;
map<TreeNode *, int> mm;//用于存放走 0~K-1步 的中间节点
mm[target] = 1;
q.push(target);
//bfs
while (!q.empty())
{
int len = q.size();
//如果走到了K步
if (K == 0)
{
while (len--)
{
int temp = q.front()->val;
q.pop();
res.push_back(temp);
}
return res;
}
//没走到K步,则被该层节点所能到的所有节点放入队列,mm的作用在这就体现了
while (len--)
{
TreeNode *cur = q.front();
q.pop();
if (cur->left && !mm[cur->left])
{
q.push(cur->left);
mm[cur->left] = 1;
}
if (cur->right && !mm[cur->right])
{
q.push(cur->right);
mm[cur->right] = 1;
}
if (parent[cur] && !mm[parent[cur]])
{
q.push(parent[cur]);
mm[parent[cur]] = 1;
}
}
K--;
}
return res;
}