具有多个列表的递归排列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有多个列表的递归排列相关的知识,希望对你有一定的参考价值。

我很好奇我如何递归地执行我的permuteAndPrintValuesThreeLists_Iterative方法...我知道排序数组和执行二进制搜索的基本递归,但我无法弄清楚如何使我的方法递归。

我想使用递归的原因是因为我希望有可能添加3个以上的列表,而不需要通过添加另一个for循环来改变我的方法。

问题:如何将permuteAndPrintValuesThreeLists方法编写为recursive方法?

我的输出应该是:

1 1 10 10 100 100
1 1 10 10 200 200
1 1 10 10 300 300
1 1 20 20 100 100
1 1 20 20 200 200
1 1 20 20 300 300
2 2 10 10 100 100
2 2 10 10 200 200
2 2 10 10 300 300
2 2 20 20 100 100
2 2 20 20 200 200
2 2 20 20 300 300

但它是:

1 1 10 10 100 100 
200 200 
300 300 
400 400 
20 20 100 100 
200 200 
300 300 
400 400 
3 3 10 10 100 100 
200 200 
300 300 
400 400 
20 20 100 100 
200 200 
300 300 
400 400 

final class Problem {

  public static void main(String[] args) {
    Problem p = new Problem();
    p.permuteAndPrintValuesThreeLists_Iterative();
  }

  private static List<int[]> l1;
  private static List<int[]> l2;
  private static List<int[]> l3;

  private Problem() {
    l1 = new ArrayList<>();
    l1.add(new int[] { 1, 1 });
    l1.add(new int[] { 2, 2 });

    l2 = new ArrayList<>();
    l2.add(new int[] { 10, 10 });
    l2.add(new int[] { 20, 20 });

    l3 = new ArrayList<>();
    l3.add(new int[] { 100, 100 });
    l3.add(new int[] { 200, 200 });
    l3.add(new int[] { 300, 300 });
  }

  private static void permuteAndPrintValuesThreeLists_Iterative() {
    for (int i = 0; i < l1.size(); i++) {
      for (int j = 0; j < l2.size(); j++) {
        for (int k = 0; k < l3.size(); k++) {
          printArray(l1.get(i));
          printArray(l2.get(j));
          printArray(l3.get(k));
          System.out.println();
        }
      }
    }
  }

  private static void printArray(int[] a) {
    for (int i : a) {
      System.out.println(i + " ");
    }
  }

}

到目前为止,我知道我需要一个包含3个列表的列表(在我的例子中,我添加了一个HashMap)。我也有这种解决方法,可以部分解决问题

private static Map<Integer, List<int[]>> allLists = new HashMap<>();
private static void permuteAndPrintValuesThreeLists_Recursion(List<int[]> resultList, int mapIndex) {
    if (mapIndex == allLists.size()) {
        // Debug code
        for (int[] arr : resultList)
            for (int i = 0; i < arr.length; i++)
                System.out.println(arr[i] + " ");
        resultList.clear();
        System.out.println();
        return;
    }
    for (int i = 0; i < allLists.get(mapIndex).size(); i++) {
        int[] tmpArray = allLists.get(mapIndex).get(i);
        resultList.add(tmpArray);
        permuteAndPrintValuesThreeLists_Recursion(resultList, mapIndex + 1);
    }
}
答案

通过添加try catch块,我得到了我在问题中打印的输出。我使用set为置换添加新值。

现在,如果我想要第四个列表,此方法仍然有效。

private static void solution_withRecursion(List<int[]> resultList, int mapIndex) {
    if (mapIndex == allLists.size()) {
        printListValues(resultList);
        return;
    }
    for (int i = 0; i < allLists.get(mapIndex).size(); i++) {
        int[] tmpArray = allLists.get(mapIndex).get(i);
        try {
            resultList.set(mapIndex, tmpArray);
        } catch (IndexOutOfBoundsException e) {
            resultList.add(tmpArray);
        }
        solution_withRecursion(resultList, mapIndex + 1);
    }
}


private static void printListValues(List<int[]> list) {
    for (int[] arr : list) {
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
    System.out.println();
}

以上是关于具有多个列表的递归排列的主要内容,如果未能解决你的问题,请参考以下文章

力扣-46-全排列

使用 Ruby/Erlang 迭代生成排列,无需递归或堆栈

单击ListViewItem时Android加载片段

哈斯克尔。我很困惑这个代码片段是如何工作的

executePendingTransactions 的递归入口

具有多个 backstack 的片段