【问题标题】:How would you find the number of paths to this tree in Java?你如何在 Java 中找到这棵树的路径数?
【发布时间】:2021-06-08 13:42:50
【问题描述】:

我正在尝试查找以这种方式表示的树的路径数:

1 4
2 4
3
4
-1

-1 代表结束,每个数字代表下一个节点。每条线都是一个节点,它们的编号从 0 开始。因此,在这个特定的实例中,有 3 条路径:0>1>2>3>4>-1、0>4>-1 和 0>1>4 >-1.

import java.io.*;
import java.util.*;

public class PathFinder {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ArrayList<ArrayList<String>> wholeList = new ArrayList<ArrayList<String>>();
        while (scanner.hasNext()) {
            String input = scanner.nextLine();
            
            StringTokenizer st = new StringTokenizer(input, " ");

            ArrayList<String> temp = new ArrayList<String>();
            while(st.hasMoreTokens()) {
                temp.add(st.nextToken());
            }
            wholeList.add(temp);
        }

        return count;
    }
}

【问题讨论】:

  • 0 1 4 -1 来自哪里?
  • 嗯,我要从第 0 行到第 1 行到第 4 行结束
  • 你把你的示例树画得更像一棵树?读起来很混乱
  • 第0行连接到:1 4,第1行连接到:2 4,第2行连接到:3,第3行连接到:4,第4行连接到:end(用-1表示)
  • 一个。图表的数字表示不清楚。在我看来,它看起来像 0>1、0>4、1>2、1>4、2>3、3>4、4>-1。湾。硬编码数据而不是使用扫描仪。 C。我没有dfs代码。

标签: java search tree depth-first-search breadth-first-search


【解决方案1】:

我建议您更改数组,使其包含整数而不是字符串。然后你可以使用递归解决方案:

import java.io.*;
import java.util.*;

public class PathFinder {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        List<List<Integer>> wholeList = new ArrayList<>();
        while (scanner.hasNext()) {
            String input = scanner.nextLine();
            
            StringTokenizer st = new StringTokenizer(input, " ");

            List<Integer> temp = new ArrayList<>();
            while(st.hasMoreTokens()) {
                temp.add(Integer.valueOf(st.nextToken()));
            }
            wholeList.add(temp);
        }
        countRoutes(wholeList, 0);
        System.out.println(count);
    }
    
    private static int count = 0;

    private static void countRoutes(List<List<Integer>> tree, int nodeFrom) {
        for (Integer target : tree.get(nodeFrom)) {
            if (-1 == target) {
                count++;
            } else {
                countRoutes(tree, target);
            }
        }
    }
}

如果你想查看路线,你可以稍微修改一下方法:

private static void printRoutes(List<List<Integer>> tree, int nodeFrom, String route) {
    for (Integer target : tree.get(nodeFrom)) {
        if (-1 == target) {
            count++;
            System.out.println(route + "->-1");
        } else {
            printRoutes(tree, target, route + "->" + target);
        }
    }
}

并从主程序调用它

printRoutes(wholeList, 0, "0");

2021 年 3 月 3 日更新

一种更有效的方法是缓存从给定节点到终点的路径数:

private static int countRoutes(List<List<Integer>> tree, 
                               int nodeFrom, 
                               int[] pathsNumber)
{
    if (nodeFrom == -1) {
        return 1;
    }
    if (pathsNumber[nodeFrom] >= 0) {
        return pathsNumber[nodeFrom];
    }

    int sum = 0;
    for (Integer target : tree.get(nodeFrom)) {
        sum += countRoutes(tree, target, pathsNumber);
    }
    pathsNumber[nodeFrom] = sum;
    return sum;
}

然后在main方法中初始化数组pathsNumber并调用该方法如下(-1表示我们还没有计算出通往该节点出口的路径数):

int[] pathsNumber = new int[wholeList.size()];
Arrays.fill(pathsNumber, -1);
System.out.println(countRoutes(wholeList, 0, pathsNumber));

【讨论】:

  • 非常感谢您!这很有帮助
  • 出于某种原因,这真的很慢。我正在尝试添加备忘录。但是,还是不够好
  • 您的原始帖子中没有关于性能要求的信息。您可以尝试更新版本,它应该更快,因为它不会再次从已访问的节点构造路径。
猜你喜欢
  • 1970-01-01
  • 2020-10-11
  • 2011-11-28
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
相关资源
最近更新 更多