我必须找到并返回通用树中的下一个更大的节点,几乎所有的测试用例都运行正常并给出正确的输出,只有一个测试用例出错了,它可能是任何东西。我已多次调试我的程序,无法弄清楚可能出现的错误是什么?实际上我在做什么我正在比较递归为我提取的所有下一个更大的节点并将它们相互比较并最终找到正确的节点?我会受到一点帮助,不胜感激。
代码
/* TreeNode structure
class TreeNode<T> {
T data;
ArrayList<TreeNode<T>> children;
TreeNode(T data){
this.data = data;
children = new ArrayList<TreeNode<T>>();
}
}*/
public static TreeNode<Integer> findNextLargerNode(TreeNode<Integer> root, int n){
if(root==null)
return root;
if(root.children.size()==0)
{
if(root.data>n)
{
return root;
}
else
return null;
}
TreeNode<Integer> count[] = new TreeNode[root.children.size()];
for(int i=0;i<root.children.size();i++)
{
count[i] = findNextLargerNode(root.children.get(i),n);
}
int nextLarger=Integer.MAX_VALUE;
TreeNode<Integer> next = null;
for(int i=0;i<count.length;i++)
{
if(count[i]!=null)
{
if(count[i].data>n && count[i].data<nextLarger)
{
nextLarger = count[i].data;
next = count[i];
}
}
}
if(next!=null)
{
if(root.data>n && root.data<next.data)
return root;
else
return next;
}
else
return null;
}
答案 0 :(得分:1)
我看到一个极端测试可能会失败:如果正确答案是一个包含数据Integer.MAX_VALUE
的节点,那么您的代码将返回null
而不是该节点。
对代码进行最少更改的解决方案是替换:
count[i].data<nextLarger
使用:
count[i].data<=nextLarger
这样,即使next
为count[i].data
,您仍然可以为Integer.MAX_VALUE
提供非空值。
注意:如果要将两个for
循环合并为一个循环,则不需要使用count
数组,而只需要使用单个节点变量。
答案 1 :(得分:1)
最后,我在代码中发现了这个错误。它位于以下部分。
if(next!=null)
{
if(root.data>n && root.data<next.data)
return root;
else
return next;
}
else
return null;
假设next == null
然后else
将被执行,这将返回null
。这是错误的,因为root
也可能是下一个更大的节点,因此我还必须检查该条件
正确的版本是:
if(next!=null)
{
if(root.data>n && root.data<next.data)
return root;
else
return next;
}
else
{
if(root.data>n)
return root;
else
return null;
}
答案 2 :(得分:1)
尝试
public class Test {
class TreeNode<T> {
T data;
List<TreeNode<T>> children;
TreeNode(T data) {
this.data = data;
children = new ArrayList<TreeNode<T>>();
}
public TreeNode<T> findNextNode(T n,Comparator<T> comp) {
if (comp.compare(data , n) < 0) {
return this;
}
if (children.size() == 0) {
return null;
}
for (int i = 0; i < children.size(); i++) {
TreeNode<T> node= children.get(i).findNextNode(n,comp);
if(node!=null)return node;
}
return null;
}
}
要在代码中显示一些错误,我在testForYourCode
中提供test(见下文)。测试返回意外结果。值为4
的第二个孩子胜出错误。
在TreeNode<T>.findNextNode
中,我提供了“重构”版本。不确定它是否符合您的要求。两个测试testForModifiedCode
和testForModifiedCodeComplex
显示了refactored
版本的行为方式。
我没有编写只能处理TreeNode<Integer>
的函数,而是决定编写一个适用于所有类型的泛型函数。
将实际比较委托给Comparator对象。必须将Comparator的实例传递给findNextNode方法。这可以使用Java 8 lambda语法即时完成,例如(a,b)->{return b-a;}
。这为实现增加了一些灵活性。通过更改比较器,您还可以使用(a,b)->{return a-b;}
搜索“下一个较小节点”。
如果入口节点满足Comparator.compare实现定义的条件,则算法将停止。否则,从第一个子节点开始执行深度搜索(等等)。一旦节点与比较标准匹配,算法就会停止。如果没有节点匹配,则返回null。
package stack43210199;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.junit.Assert;
public class Test {
class TreeNode<T> {
T data;
List<TreeNode<T>> children;
TreeNode(T data) {
this.data = data;
children = new ArrayList<TreeNode<T>>();
}
public TreeNode<T> findNextNode(T n,Comparator<T> comp) {
if (comp.compare(data , n) < 0) {
return this;
}
if (children.size() == 0) {
return null;
}
for (int i = 0; i < children.size(); i++) {
TreeNode<T> node= children.get(i).findNextNode(n,comp);
if(node!=null)return node;
}
return null;
}
}
@org.junit.Test
public void testForYourCode() {
TreeNode<Integer> root = buildNode(0);
TreeNode<Integer> firstChild = buildNode(5);
TreeNode<Integer> secondChild = buildNode(4);
TreeNode<Integer> thirdChild = buildNode(5);
root.children.add(firstChild);
root.children.add(secondChild);
root.children.add(thirdChild);
//Arrg - not as expected
Assert.assertEquals(secondChild, findNextLargerNode(root, 0));
}
@org.junit.Test
public void testForModifiedCode() {
TreeNode<Integer> root = buildNode(2);
TreeNode<Integer> firstChild = buildNode(5);
TreeNode<Integer> secondChild = buildNode(4);
TreeNode<Integer> thirdChild = buildNode(5);
TreeNode<Integer> fourthChild = buildNode(1);
root.children.add(firstChild);
root.children.add(secondChild);
root.children.add(thirdChild);
thirdChild.children.add(fourthChild);
//find next greater
Assert.assertEquals(firstChild, root.findNextNode(2,(a,b)->{return b-a;}));
//find next lesser
Assert.assertEquals(fourthChild, root.findNextNode(2,(a,b)->{return a-b;}));
}
@org.junit.Test
public void testForModifiedCodeComplex() {
TreeNode<Integer> root = buildNode(2);
TreeNode<Integer> firstChild = buildNode(2);
TreeNode<Integer> secondChild = buildNode(4);
TreeNode<Integer> thirdChild = buildNode(5);
TreeNode<Integer> fourthChild = buildNode(1);
TreeNode<Integer> sixthChild = buildNode(8);
firstChild.children.add(fourthChild);
firstChild.children.add(sixthChild);
root.children.add(firstChild);
root.children.add(secondChild);
root.children.add(thirdChild);
//find next greater
Assert.assertEquals(sixthChild, root.findNextNode(2,(a,b)->{return b-a;}));
//find next lesser
Assert.assertEquals(fourthChild, root.findNextNode(2,(a,b)->{return a-b;}));
}
private TreeNode<Integer> buildNode(int i) {
return new TreeNode<Integer>(new Integer(i));
}
public static TreeNode<Integer> findNextLargerNode(TreeNode<Integer> root, int n) {
if (root == null)
return root;
if (root.children.size() == 0) {
if (root.data > n) {
return root;
}
else
return null;
}
TreeNode<Integer> count[] = new TreeNode[root.children.size()];
for (int i = 0; i < root.children.size(); i++) {
count[i] = findNextLargerNode(root.children.get(i), n);
}
int nextLarger = Integer.MAX_VALUE;
TreeNode<Integer> next = null;
for (int i = 0; i < count.length; i++) {
if (count[i] != null) {
if (count[i].data > n && count[i].data < nextLarger) {
nextLarger = count[i].data;
next = count[i];
}
}
}
if (next != null) {
if (root.data > n && root.data < next.data)
return root;
else
return next;
} else {
if (root.data > n)
return root;
else
return null;
}
}
}
答案 3 :(得分:0)
TreeNode通常看起来像这样。
class TreeNode<T extends Comparable<T>> {
T data;
TreeNode<T> left, right;
TreeNode(T data){
this.data = data;
}
public TreeNode<T> findNextLargerNode(T t) {
if (data.compareTo(t) <= 0)
return right == null ? null : right.findNextLargerNode(t);
T found = left == null ? null : left.findNextLargerNode(t);
return found == null ? this : found;
}
}