版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/qq_41855420,未经博主允许不得转载。 https://blog.csdn.net/qq_41855420/article/details/91312978
给定一个二叉树(具有根结点 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" 实际上是树上的结点。
上面的输入仅仅是对这些对象进行了序列化描述。
提示:
给定的树是非空的,且最多有 K 个结点。
树上的每个结点都具有唯一的值 0 <= node.val <= 500 。
目标结点 target 是树上的结点。
0 <= K <= 1000.
如果把这棵二叉树看成一个无向图,那么题目就转化为图的节点距离搜索问题,因此有个思路就是把这个二叉树转换为类似图的结构,然后使用深度、广度优先搜索即可。不过这道题也可以直接搜索,直接使用二叉树的后序遍历。
这种算法的关键就是如何处理回归问题,比如
[0,2,1,null,null,3]
target = 3
K = 3
当我们使用后序遍历搜索到target这个位置,我们需要通过绿色的线路回归到distance = K的地方。
/**
* 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:
vector<int> resVec;
vector<int> distanceK(TreeNode* root, TreeNode* target, int K) {
//特殊情况:root或者target为空
if (root == NULL || target == NULL){
return {};
}
//特殊情况:K == 0,只有target本身
if (K == 0){
return {target->val};
}
myDFS(root, target, K);//后序遍历二叉树
return resVec;
}
//后序遍历以root为根的二叉树,并且返回root的父节点到target的距离
int myDFS(TreeNode* root, TreeNode* target, int K){
if (root == NULL){
return -1;//返回-1,说明距离无穷大
}
if (root == target){//特殊情况
helper(root, K);//取出以root为根的距离为K的元素
return 1;//root的父节点到target的距离为1
}
//如果target在root的左子树
int distance = myDFS(root->left, target, K);
//更新distance记录的是root->left的父节点root到target的距离
if (distance != -1 && K >= distance){
if (K == distance){//如果root到target的距离刚好为K
resVec.push_back(root->val);
return -1;
}
else {
//否则搜索root->right距离target == K的节点
//root到target的距离为distance,root->right到target的距离为distance + 1
helper(root->right, K - (distance + 1));
return distance + 1;
}
}
//如果target在root的右子树
distance = myDFS(root->right, target, K);
//更新distance记录的是root->right的父节点root到target的距离
if (distance != -1 && K >= distance){
if (K == distance){//如果root到target的距离刚好为K
resVec.push_back(root->val);
return -1;
}
else {
//否则搜索root->left距离target == K的节点
//root到target的距离为distance,root->left到target的距离为distance + 1
helper(root->left, K - (distance + 1));
return distance + 1;
}
}
return -1;//否则target到root的父节点的距离无穷大
}
//获取以root为根,到达root的距离为K的节点
void helper(TreeNode* root, int K){
if (root == NULL || K < 0){
return;
}
if (K == 0){
resVec.push_back(root->val);
}
else{
helper(root->left, K - 1);
helper(root->right, K - 1);
}
}
};