在java中,树中从0开始的最长路径

在java中,树中从0开始的最长路径,java,algorithm,tree,Java,Algorithm,Tree,我有一棵树,有N个节点和N-1个连接它们的链接 节点用范围为[0到N-1]的不同数字进行标记 链路以这样的方式连接节点,即每对不同的节点通过直接链路或沿由直接链路组成的路径连接 从任何其他节点到达任何节点只有一种方法 现在,对于我的任务,开始节点是0。我希望访问尽可能多的节点。 我不想访问任何节点超过一次,我只能沿着直接链接移动。 根据我的任务,我可能在任何节点结束,我只想找到最长的路径 但这里有一个限制,我最多可以访问逻辑中的一个奇数节点(1、3、5等) 我的程序的输入表示为数组“A”,这样:

我有一棵树,有N个节点和N-1个连接它们的链接

节点用范围为[0到N-1]的不同数字进行标记

链路以这样的方式连接节点,即每对不同的节点通过直接链路或沿由直接链路组成的路径连接

从任何其他节点到达任何节点只有一种方法

现在,对于我的任务,开始节点是0。我希望访问尽可能多的节点。 我不想访问任何节点超过一次,我只能沿着直接链接移动。 根据我的任务,我可能在任何节点结束,我只想找到最长的路径

但这里有一个限制,我最多可以访问逻辑中的一个奇数节点(1、3、5等)

我的程序的输入表示为数组“A”,这样:

A[0] = 0;
A[P] = Q and P!= 0, then there is a direct link between nodes P & Q.
具有10个节点和9个链接的示例:

Lets say A={0,9,0,2,6,8,0,8,3,0};


4--6--0--2--3--8--5
      |        |
      9        7
      |
      1(one)


This example should return 4, as there is a longest path 0->2->3->8. Node 3 is the only odd numbered node here.
A = [0,0,0,1,6,1,0,0]

          7 
          |     
    5--1--0--6--4   
       |  |
       3  2 

This example should return 3, as there is a path longest 0->6->4.
示例2:

Lets say A={0,9,0,2,6,8,0,8,3,0};


4--6--0--2--3--8--5
      |        |
      9        7
      |
      1(one)


This example should return 4, as there is a longest path 0->2->3->8. Node 3 is the only odd numbered node here.
A = [0,0,0,1,6,1,0,0]

          7 
          |     
    5--1--0--6--4   
       |  |
       3  2 

This example should return 3, as there is a path longest 0->6->4.
我想出了以下代码来解决这个程序:

public static int longestPath(int[] T) {
        List<Integer>[] nodes = new ArrayList[T.length];

        for (int i = 0; i < T.length; i++) {
            nodes[i] = new ArrayList<>();
        }
        for (int i = 0; i < T.length; i++) {
            if (T[i] != i) {
                nodes[i].add(T[i]);
                nodes[T[i]].add(i);
            }
        }
        List<Integer> connectedNodes = nodes[0];

        int longestPath = 0;
        for (int i = 0; i < connectedNodes.size(); i++) {
            int nextNode = connectedNodes.get(i);
            int count = 1;
            Set<Integer> set = new HashSet<>();
            set.add(0);
            set.add(nextNode);
            int odds = 0;
            if (nextNode % 2 != 0) {
                odds++;
            }
            count++;
            while (true) {
                List<Integer> arrayList = nodes[nextNode];
                arrayList.sort(null);
                int next = arrayList.get(arrayList.size() - 1);
                if (!set.contains(next)) {
                    set.add(next);
                    if (next % 2 != 0) {
                        odds++;
                        if (odds >= 2) {
                            break;
                        }
                    }
                    count++;
                    nextNode = next;
                } else {
                    break;
                }
            }
            longestPath = Math.max(count, longestPath);
        }

        return longestPath;
    }
公共静态int longestPath(int[]T){
List[]nodes=newarraylist[T.length];
对于(int i=0;i=2){
打破
}
}
计数++;
nextNode=next;
}否则{
打破
}
}
longestPath=Math.max(count,longestPath);
}
返回最长路径;
}
当我在上个月的一次考试中尝试这个程序时,这个程序只适用于这两个测试用例,但它没有通过其他我不知道的测试,并且得到了16分(满分100分)

我正在努力找出代码中的正确方法和问题


你能帮助我这个代码中的问题是什么以及如何解决这个问题吗。我还想打印实际的最长路径,如例1的
0->2->3->8
和例2的
0->6->4

您可以通过深度优先搜索找到答案

首先,您必须将输入数组转换为邻接列表,这将在以后的深度优先搜索中使用。您可以这样做:

List<List<Integer>> tree = new ArrayList<>();

int longestPath(int[] T) {
  int n = T.length;
  for (int i = 0; i < n; i++) {
    tree.add(new ArrayList<>());
  }
  //we do this to denote that there is an edge between u and T[u] and vice-versa
  for (int u = 0; u < n; u++) {
    if (u != T[u]) {
      tree.get(u).add(T[u]);
      tree.get(T[u]).add(u);
    }
  }

  return recurse(0, -1, false);
}

当我们从没有父节点的节点
0
开始时(即,我们可以使用
-1
来说明这一点),我们调用
递归(0,-1,false)

而不是我们调试您的算法来为您解决问题。也许你可以自己调试一下。如果这个方法不起作用,也可以尝试不同的方法?看看对呼吸优先或深度优先搜索的一些修改是否可以简化您的算法。我不完全确定,但我认为您目前的问题在于
int next=arrayList.get(arrayList.size()-1)。似乎只使用排序后的
arrayList
中最大的下一个节点,而不是将所有节点都检查为有效路径。我会尝试将其作为递归方法重写到您的代码中,这样您可以在到达末尾或遇到第二个奇数值时返回并尝试其他节点,这样您就可以验证所有可能的路径。这是否回答了您的问题?示例2的解决方案不应该是0->6->4吗?@SaiBot,是的,正确,我现在更新了它。你能告诉我在哪里需要使用这个代码吗?我的程序的输入是一个数组,因此无法关联如何使用它。我使用示例输入测试了
{0,9,0,2,6,8,0,8,3,0}
{0,0,0,1,6,1,0,0}
我得到的输出是5和4,而不是4和3。我更新了我的答案,谢谢。不,应该没问题。