如何找到列表的所有路径?

时间:2019-03-16 08:48:12

标签: java algorithm graph

我有一个这样的列表:

[[A], [B, C, D], [E, F], [G]]

对于Java代码初始化:

 List<List<String>> data = new ArrayList<>();
 data.add(Arrays.asList("A"));
 data.add(Arrays.asList("B", "C", "D"));
 data.add(Arrays.asList("E", "F"));
 data.add(Arrays.asList("G"));

并希望得到类似波纹管的结果:

[[A,B,E,G],[A,B,F,G], [A,C,E,G],[A,C,F,G],[A,D,E,G],[A,D,F,G]]

该怎么做?非常感谢。

2 个答案:

答案 0 :(得分:0)

您可以编写一个递归算法来解决此问题。对于每个递归调用,该算法在图形中向下移动一层。要点是,首先要计算当前所在图层下的所有路径,然后将当前图层中的所有节点添加到这些路径。

这里有一些伪代码可以帮助您前进:

paths(input) {
    if input is empty -> return empty // This is your base case

    currentNodes = input[0]
    subPaths = paths(input.tail) // Recursive call with the rest of your input

    if subPaths is empty -> return input // The paths from the last layer is itself

    result = emptyList()
    for all nodes in currentNodes
        for all paths in subPaths
            prepend node to path and add to result

    return result
}

答案 1 :(得分:0)

感谢@OmriAttiya。现在我给出答案了。

这是一个Cartesian Product问题。

  

如果您使用番石榴库,则只需一行

List<List<String>> cartesian = Lists.cartesianProduct(operationTypeList);
  

cartesianNoRecursive

public static List<List<String>> cartesianNoRecursive(List<List<String>> data) {
    int total = 1;
    for (int i = 0; i < data.size(); i++) {
        total *= data.get(i).size();
    }
    List<List<String>> result =  new ArrayList<>(total);
    for (int i = 0; i < total; i++) {
        result.add(new ArrayList<>());
    }
    int now = 1;
    // used times for every element in one loop
    int itemLoopNum = 1;
    // total  times of every element
    int loopPerItem = 1;
    for (int i = 0; i < data.size(); i++) {
        List<String> temp = data.get(i);
        now = now * temp.size();
        //index of target result
        int index = 0;
        int currentSize = temp.size();
        itemLoopNum = total / now;
        loopPerItem = total / (itemLoopNum * currentSize);
        // index of data
        int dataIndex = 0;
        for (int j = 0; j < temp.size(); j++) {
            for (int k = 0; k < loopPerItem; k++) {
                if (dataIndex == temp.size()) {
                    dataIndex = 0;
                }
                for (int m = 0; m < itemLoopNum; m++) {
                    result.get(index).add(temp.get(dataIndex));
                    index++;
                }
                dataIndex++;

            }
        }
    }
    return result;
}
  

cartesianRecursive

public static List<List<String>> cartesianRecursive(List<List<String>> list) {
    List<List<String>> result = new ArrayList<List<String>>();
    int numSets = list.size();
    String[] tmpResult = new String[numSets];
    cartesianRecursive(list, 0, tmpResult, result);

    return result;
}

public static void cartesianRecursive(List<List<String>> list, int n, String[] tmpResult, List<List<String>> result) {
    if (n == list.size()) {
        result.add(new ArrayList<String>(Arrays.asList(tmpResult)));
        return;
    }

    for (String i : list.get(n)) {
        tmpResult[n] = i;
        cartesianRecursive(list, n + 1, tmpResult, result);
    }
}