Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用根到节点路径方法超出了最低共同祖先时间限制_C++_Tree_Time Complexity_Binary Tree_Lowest Common Ancestor - Fatal编程技术网

C++ 使用根到节点路径方法超出了最低共同祖先时间限制

C++ 使用根到节点路径方法超出了最低共同祖先时间限制,c++,tree,time-complexity,binary-tree,lowest-common-ancestor,C++,Tree,Time Complexity,Binary Tree,Lowest Common Ancestor,我已经实施了LCA问题的解决方案。问题是给定一棵二叉树,在树中找到两个给定节点的最低共同祖先LCA。 我使用的方法是找到从根到给定2个节点的路径,并将这2条路径存储在向量中。 从rootthe path开始比较两条路径中的节点,直到LCA应匹配p和q, 因此,路径中发生不匹配之前的节点将是LCA 但仅在Leetcode中就通过了29/31个测试用例,对于非常大的输入,超过了时间限制。 代码如下: /** *二叉树节点的定义。 *树状结构{ *int-val; *TreeNode*左; *Tree

我已经实施了LCA问题的解决方案。问题是给定一棵二叉树,在树中找到两个给定节点的最低共同祖先LCA。 我使用的方法是找到从根到给定2个节点的路径,并将这2条路径存储在向量中。 从rootthe path开始比较两条路径中的节点,直到LCA应匹配p和q, 因此,路径中发生不匹配之前的节点将是LCA

但仅在Leetcode中就通过了29/31个测试用例,对于非常大的输入,超过了时间限制。 代码如下:

/** *二叉树节点的定义。 *树状结构{ *int-val; *TreeNode*左; *TreeNode*对; *TreeNodeint x:valx,leftNULL,rightNULL{} * }; */ 类解决方案{ 公众: 向量路径; void pathuntilnodereenode*根,向量res,TreeNode*p{ ifroot==NULL返回; res.push_backroot; ifroot==p{ path=res; 回来 } PathUntineNodeRoot->左,右,右; PathUntineNodeRoot->右,右,右,右; } TreeNode*最低公度StorTreenode*根,TreeNode*p,TreeNode*q{ ifroot==NULL返回NULL; 向量res; pathUntilNoderoot,res,p; 向量路径1=路径; pathUntilNoderoot,res,q; 向量路径2=路径; int i;
对于i=0;i问题在于,您的代码使所有向量指针引用同一个向量。但您需要将path1和path2作为单独的向量。因此,如果在执行path=res之后,您有另一个res.push\u backroot,这将影响已成为res同义词的path

其次,即使在找到匹配项后,递归搜索仍会继续搜索。这是浪费时间。它应该尽快退出递归树。因此,如果它从节点左子级(找到匹配项的位置)中的搜索返回,则不应该继续在节点右子级中的搜索

有几种方法可以解决第一个问题,但基本上这两条路径必须是独立的向量。一种方法是,如果找到递归函数,则返回路径;如果没有,则返回空路径。这种方法将反向构建路径,但这很容易处理:

vector<TreeNode*> notfound;

vector<TreeNode*> pathUntilNode(TreeNode* root, TreeNode* p) {
    if (root == NULL) return notfound;
    if (root == p) return { root }; // found: start a new path
    vector<TreeNode*> path = pathUntilNode(root->left, p);
    // only look in the other subtree if no success yet...
    if (path == notfound) path = pathUntilNode(root->right, p);
    if (path != notfound) path.push_back(root);  // success: extend the path
    return path;
}

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    vector<TreeNode*> path1 = pathUntilNode(root, p);
    vector<TreeNode*> path2 = pathUntilNode(root, q);
    reverse(path1.begin(), path1.end());
    reverse(path2.begin(), path2.end());
    // no change below this point
    int i;
    for (i = 0; i < min(path1.size(), path2.size()); i++) {
        if (path1[i] != path2[i])
            return path1[i-1];
    }
    return path1[i-1];
}