LeetCode 二叉树中所有距离为K的节点(后序遍历+深度优先遍历)

版权声明:本文为博主原创文章,博客地址: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.

\color{blue}思路分析: 如果把这棵二叉树看成一个无向图,那么题目就转化为图的节点距离搜索问题,因此有个思路就是把这个二叉树转换为类似图的结构,然后使用深度、广度优先搜索即可。不过这道题也可以直接搜索,直接使用二叉树的后序遍历。
这种算法的关键就是如何处理回归问题,比如

[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);
        }
    }
};

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/91312978