📌  相关文章
📜  查找包含集合V中所有节点的节点U,该集合V距从根到U的路径的距离最大为1(1)

📅  最后修改于: 2023-12-03 14:55:33.185000             🧑  作者: Mango

查找包含集合V中所有节点的节点U

题意描述

给定一棵二叉树和一个节点集合V,找到一个包含集合V中所有节点的节点U,使得该集合V距离从根节点到U的路径的距离最大为1。

解题思路

首先,我们需要明确题目中的一些术语和定义:

  • 二叉树:每个节点最多有两个子节点的树结构。
  • 路径:从树中的一个节点到另一个节点所经过的节点序列。
  • 二叉树的深度:根节点到最远叶子节点的最长路径上的节点数。
  • 二叉树的高度:根节点到最远叶子节点的最长路径上的边数。

根据题目要求,我们需要找到一个包含集合V中所有节点的节点U。假设这个节点U已经找到了,那么它一定可以被表示为一条从根节点到某个叶节点的路径上的某个节点。

因此,我们可以先遍历二叉树,找到所有包含集合V中的节点的路径。

然后,我们需要找到这些路径的最近公共祖先。为了保证最近公共祖先的距离最大为1,我们只需要找到距离这些路径上最近公共祖先最近的一个节点,且该节点的深度等于最近公共祖先的深度加1。

最后,我们只需要在这些符合条件的节点中选择深度最大的节点作为答案即可。

代码实现
/**
 * 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:
    TreeNode* lowestCommonAncestor(TreeNode* root, vector<TreeNode*> &nodes) {
        if (root == nullptr || nodes.empty()) {
            return nullptr;
        }

        vector<vector<TreeNode*>> paths;
        for (auto node : nodes) {
            vector<TreeNode*> path;
            if (!findPath(root, node, path)) {
                return nullptr;
            }
            paths.push_back(path);
        }

        return findLCA(paths, root->val);
    }

private:
    bool findPath(TreeNode* root, TreeNode* target, vector<TreeNode*> &path) {
        if (root == nullptr) {
            return false;
        }

        path.push_back(root);

        if (root == target) {
            return true;
        }

        if (findPath(root->left, target, path) || findPath(root->right, target, path)) {
            return true;
        }

        path.pop_back();
        return false;
    }

    TreeNode* findLCA(vector<vector<TreeNode*>> &paths, int rootVal) {
        TreeNode* lca = nullptr;
        int depth = -1;

        for (int i = 0; i < paths.size(); i++) {
            auto path1 = paths[i];
            for (int j = 0; j < path1.size(); j++) {
                if (path1[j]->val != rootVal) {
                    continue;
                }

                int k = 1;
                for (; k < paths.size(); k++) {
                    auto path2 = paths[(i + k) % paths.size()];
                    if (j >= path2.size() || path2[j] != path1[j]) {
                        break;
                    }
                }

                if (k == paths.size() && (lca == nullptr || depth < j)) {
                    lca = path1[j];
                    depth = j;
                }

                break;
            }
        }

        if (lca == nullptr) {
            return nullptr;
        }

        if (lca->left != nullptr && lca->right != nullptr) {
            return lca;
        }
        else if (lca->left != nullptr) {
            return lca->left;
        }
        else if (lca->right != nullptr) {
            return lca->right;
        }
        else {
            return nullptr;
        }
    }
};

以上代码为C++实现版本,其中 lowestCommonAncestor 函数用于在二叉树中查找符合要求的最近公共祖先,函数接受两个参数:二叉树的根节点和目标节点集合V。

实现思路在解题思路中已经详细讲述。

具体实现细节请参见注释。