查找树搜索失败的最低命令祖先(不是算法问题,而是Java问题)
非常简单的树问题,不知何故结果为空(应该是1,因为1是2&3的父节点),无法找到原因。该方法本身已经通过Leetcode在线评审 以下是问题的链接: 给定一棵二叉树,找到树中两个给定节点的最低共同祖先(LCA) 根据维基百科上LCA的定义:“两个节点v和w之间的最低共同祖先被定义为T中的最低节点,该节点的v和w都是其后代(我们允许一个节点是其自身的后代)。” TreeNode的定义如下:查找树搜索失败的最低命令祖先(不是算法问题,而是Java问题),java,tree,binary-tree,binary-search-tree,divide-and-conquer,Java,Tree,Binary Tree,Binary Search Tree,Divide And Conquer,非常简单的树问题,不知何故结果为空(应该是1,因为1是2&3的父节点),无法找到原因。该方法本身已经通过Leetcode在线评审 以下是问题的链接: 给定一棵二叉树,找到树中两个给定节点的最低共同祖先(LCA) 根据维基百科上LCA的定义:“两个节点v和w之间的最低共同祖先被定义为T中的最低节点,该节点的v和w都是其后代(我们允许一个节点是其自身的后代)。” TreeNode的定义如下: public class TreeNode { public int val; pub
public class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}
}
由于这一行代码,正在发生错误
if (root == null || root == t1 || root == t2)
在执行此方法时,请仔细考虑要比较的内容
TreeNode result = test.lowestCommonAncestor(root, target1, target2);
调用LCA方法时,第一条if语句中的任何条件都不会计算为true,因为没有一条语句为true,这是正确的。但是,现在让我们来看第一个递归调用
TreeNode left = lowestCommonAncestor(root.left, t1, t2);
TreeNode right = lowestCommonAncestor(root.right, t1, t2);
对于最低的公共祖先(root.left,t1,t2)
,请仔细考虑第一条if语句<在这种情况下,code>root现在是node2
,而t1和t2仍然是main中定义的节点target1
和target2
。但是等等,这就是问题发生的原因。您可能希望语句root==t1
的计算结果为true,但它的计算结果不是true,原因如下node2
和target1
是两个不同的对象,Java的==
操作符并没有做您认为它在这里做的事情。使用=
运算符比较对象时,将比较对象的地址,而不是对象的实际内容。因此,由于node2
和target1
在程序中占用不同的数据空间,因此它们的地址不同。您将看到=
运算符更常用于比较Java中的基本类型,如int和char,因为它与比较对象不同。这就是为什么您会看到Java中用于比较字符串的.equals
方法,因为字符串是对象
那么解决方案是什么?
在TreeNode类中创建一个equals
方法,该方法返回一个布尔值并将另一个TreeNode对象作为参数。另外,请确保此方法是实例方法而不是静态方法,以便此方法在代码中的执行如下所示:
public boolean equals(TreeNode node){ //method address
//rest of the method has to be implemented yourself
//ask yourself, how are two treenodes considered equal in your situation?
}
最后,将root==t1
替换为
root.equals(t1)
root.equals(t2)
和root==t2
with
root.equals(t1)
root.equals(t2)
您可以尝试以下方法:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode t1, TreeNode t2) {
if((search(root,t1)==null)||(search(root,t2)==null)
return null;
if(search(root.left,t1)!=null)
{
if(search(root.left,t2)!=null)
return lowestCommonAncestor(root.left,t1,t2);
}
else if(search(root.right,t2)!=null)
return lowestCommonAncestor(root.right,t1,t2);
return root;
}
search
method搜索树中的树节点,我把它留给您;)
解释
首先,我们检查root
树是否包含节点t1
和t2
,如果root
不包含其中一个,我们将返回null,因为没有祖先
之后,我们在root.left
中搜索t1
,如果我们在root.left
中搜索t2
,如果我们找到它,那么最不常见的祖先必须在root.left
中,但我们还不能确定它,所以我们递归地调用最低共同祖先(root.left,t1,t2)
的方法
现在,如果我们在右边找到t2
,在右边找到t1
,那么最不常见的祖先在右边,我们递归调用
在所有其他情况下,我们返回root,因为t1
位于左侧,t2
位于右侧,反之亦然。在这两种情况下,root是一个共同祖先(因为我们的检查),所以它是最不共同的祖先
如果允许我们在每个TreeNode
中都有一个parent
指针,那么更好的算法是从t1.parent
向树上走,并且只在p=t1时停止。parent
(或者t1.parent.parent
,你知道了)是t2
的祖先 树节点不需要指向父节点的指针吗?这是Leetcode提供的树节点,所以我不认为指针是一个选项。你是对的,我忽略了我试图比较两个对象。因此,我认为最简单的方法是将if(root==null | | root==t1 | | root==t2)更改为if(root==null | | root.val==t1.val | root.val==t2.val)