用于查找最低共同祖先的代码不适用于某些测试用例
Code for finding Lowest Common Ancestor is not working for some test cases
我正在从Hackerrank(https://www.hackerrank.com/challenges/binary-search-tree-lowest-common-ancestor/copy-from/158548633(进行这个练习 在本练习中,我们得到了一个指向二叉搜索树根的指针以及两个值v1
和v2
。我们需要返回二叉搜索树中v1
和v2
的最低共同祖先 (LCA(。我们必须完成函数lca
.它应该返回一个指针,指向给定的两个值中最低的公共祖先节点。
LCA 具有以下参数:
-
root:指向二叉搜索树的根节点的指针
-
v1:节点数据值
- v2:节点数据值
我知道递归解决方案更容易,但我尝试了这种方法,找不到测试用例失败的任何原因。下面提到的解决方案仅通过 6/10 个测试用例。我看不到所有 4 个失败的测试用例,但我可以提到 1 个测试用例。
这是我的代码
/*The tree node has data, left child and right child
class Node {
int data;
Node* left;
Node* right;
};
*/
vector<Node*> find(int v, Node* root)
{
vector<Node*> ar;
if (v == root->data) {
ar.push_back(root);
return ar;
}
if (v > root->data) {
ar.push_back(root);
find(v, root->right);
}
if (v < root->data) {
ar.push_back(root);
find(v, root->left);
}
ar.push_back(root);
return ar;
}
Node* lca(Node* root, int v1, int v2)
{
//this vector contains the nodes in path
//to reach from root to node
vector<Node *> a, b;
//find function return the vector
a = find(v1, root);
b = find(v2, root);
//index of the LCA in the vector
int res = 0;
//traversing the two vectors from
//beg to end if two nodes are same
//update the value of res. Final updated
//value will give us LCA
int n = b.size();
if (a.size() < b.size())
n = a.size();
int i = 0;
while (i < n) {
if (a[i] == b[i])
res = i;
i++;
}
return a[res];
}
失败的测试用例:
8
8 4 9 1 2 3 6 5
1 2
预期产出:
1
我的输出:
8
需要帮助来调试代码并找到此方法中的漏洞。
下面的伪代码可用于生成LCA问题的代码。
///
递归调用 LCA 函数,一个用于左子树,一个用于右子树。如果节点为 null,则返回 null,否则
如果节点的值等于任何值 v1, v2,则只需返回此节点,
否则递归调用子树。
现在,当您收到 2 个递归调用的结果时,请检查 ->
如果两者都为 null,则返回 null
如果一个为空,另一个不为空,则返回非空节点,
如果两者都不为 null,则返回根注释本身。
你的算法无法工作
- 在查找中,递归调用产生的向量丢失了,所以就像你不做这些调用一样,最后你只得到初始调用产生的向量
- 在LCA中,即使假设找到正确的事情,您假设答案在 2 个向量中的相同排名,为什么?
一种方法是:
Node * Node::lca(int v1, int v2) {
if ((data == v1) || (data == v2))
return this;
Node * r = (right == NULL) ? NULL : right->lca(v1, v2);
Node * l = (left == NULL) ? NULL : left->lca(v1, v2);
return ((r != NULL) && (l != NULL))
? this
: ((r == NULL) ? l : r);
}
一个完整的例子:
#include <iostream>
#include <vector>
#include <iomanip>
class Node {
private:
int data;
Node* left;
Node* right;
public:
Node(int d) : data(d), left(NULL), right(NULL) {}
void insert(int d);
void draw(int level = 1) const;
Node * lca(int v1, int v2);
};
void Node::insert(int d) {
Node * n = new Node(d);
Node * t = this;
for (;;) {
if (d > t->data) {
if (t->right == NULL) {
t->right = n;
return;
}
t = t->right;
}
else if (t->left == NULL) {
t->left = n;
return;
}
else
t = t->left;
}
}
void Node::draw(int level) const {
if (right != NULL)
right->draw(level + 1);
else
std::cout << std::setw(level + 1) << '/' << std::endl;
std::cout << std::setw(level) << data << std::endl;
if (left != NULL)
left->draw(level + 1);
else
std::cout << std::setw(level + 1) << '' << std::endl;
}
Node * Node::lca(int v1, int v2) {
if ((data == v1) || (data == v2))
return this;
Node * r = (right == NULL) ? NULL : right->lca(v1, v2);
Node * l = (left == NULL) ? NULL : left->lca(v1, v2);
return ((r != NULL) && (l != NULL))
? this
: ((r == NULL) ? l : r);
}
int main()
{
Node r(8);
std::vector<int> v = { 4, 9, 1, 2, 3, 6, 5 };
for (auto d : v)
r.insert(d);
r.draw();
std::cout << "----------------" << std::endl;
Node * l;
std::cout << "lca for 1 & 2" << std::endl;
l = r.lca(1, 2);
if (l != NULL)
l->draw();
std::cout << "----------------" << std::endl;
std::cout << "lca for 5 & 2" << std::endl;
l = r.lca(5, 2);
if (l != NULL)
l->draw();
}
编译和执行:
pi@raspberrypi:/tmp $ g++ -Wall lca.cpp
pi@raspberrypi:/tmp $ ./a.out
/
9
8
/
6
/
5
4
/
3
2
1
----------------
lca for 1 & 2
/
3
2
1
----------------
lca for 5 & 2
/
6
/
5
4
/
3
2
1
pi@raspberrypi:/tmp $
相关文章:
- "std::forward"和"std::move"真的不生成代码吗?
- bash脚本在使用popen()时不返回代码以调用C ++程序
- 为什么向量不在代码块中运行?
- OpenGL/Glew C++纹理不适用
- 我们可以在层次结构中创建多个纯虚拟接口及其实现而不会代码爆炸吗?
- 在运行时,何时完全初始化 std 库才能在不破坏代码的情况下使用它?
- 当我在 windows7 中安装程序时,我指定的字体大小不适用
- accelerator.cu(8): 错误:属性"managed"在这里不适用?
- 如何解决错误 C2719 在 Visual Studio 2010 C++ 中不存在代码行时
- 在具有不兼容代码的C++代码中使用 C 库
- 不重复代码的继承
- typedef X=<T>T::UserType1,但如果不适用,typedef X<T>=UserType2
- 如何在不更改代码的情况下为所有C++函数设置属性
- 我不明白代码的某些部分
- 用C++编写一个程序,对一个简单的序列求和:1/N + 2/N-1 + 3/N-2+ ...不适用
- 文件处理 - 错误:与 while 循环 (C++) 中的"运算符>>"不匹配(代码::块)
- 如何在不打开代码::块的情况下运行 c++ 程序
- 编译时错误,看不到代码中的明显错误
- 修复错误:在不更改代码的情况下获取临时地址
- 重载C++模板函数而不复制代码