【问题标题】:Print all the combinations of elements in a 2D Matrix打印二维矩阵中的所有元素组合
【发布时间】:2015-04-27 20:15:52
【问题描述】:

打印大小为 m * n 的矩阵中的所有元素组合。

示例:
1 3 5
2 6 7

预期输出:
2、1
2 , 3
2、5
6、1
6、3
6 , 5
7、1
7、3
7 , 5

规则:
- 每个组合都从矩阵的底部开始,然后向顶部进行。不过它可能会切换列。
- 每个组合的元素数应等于行数。
- 一个组合不能有来自同一行的元素出现两次。

我永远无法为一般情况找出解决方案。我可以使用 3 个循环。但我想了解递归解决方案。我使用 Java。

【问题讨论】:

  • 请发布您尝试过的内容。参考this&this
  • 还有thisthis
  • 这不是代码请求。我只想了解如何使用递归。无需编写任何代码。
  • 我有一个大小为 2,3 的数组的解决方案。我为此使用了 3 个循环。但是随着尺寸的增加,它是不可行的。太天真了。
  • 寻找 n 选择 k 带回溯的递归。

标签: java algorithm matrix


【解决方案1】:

这是解决此问题的一种非递归方法(虽然不是很漂亮,但它适用于您的输入)。我知道您对递归感兴趣,但目前我没有类似的东西给您。通常,由于我处理的问题的大小,我会避免递归(即使在-Xmx60G 时,由于递归堆栈的大小导致的恒定堆空间错误)。希望这会有所帮助。

private static List<int[]> combos;
public static void main(String[] args){
    combos = new ArrayList<int[]>();
    generate(new int[][]{{1,3,5},{2,6,7}});
    for(int[] s : combos){
        System.out.println(java.util.Arrays.toString(s));
    }
}
private static void generate(int[][] elements) {
    int rows = elements.length;
    int[] elementsIndex = new int[rows];
    int[] elementsTotals = new int[rows];
    java.util.Arrays.fill(elementsTotals, elements[0].length);
    int curIdx = 0;
    int[] c = new int[rows];
    while(true){
        while(curIdx >= 0){
            if(curIdx == rows) {
                addCombo(c);
                curIdx--;
            }
            if(elementsIndex[curIdx] == elementsTotals[curIdx]){
                elementsIndex[curIdx] = 0;
                curIdx--;
            } else break;
        }
        if(curIdx < 0) break;
        // toggle order: 
        //  bottom up: elements[rows-curIdx-1][elementsIndex[curIdx]++]
        //  top down: elements[curIdx][elementsIndex[curIdx]++]
        c[curIdx] = elements[rows-curIdx-1][elementsIndex[curIdx]++];
        curIdx++;
    }
}
private static void addCombo(int[] c){
    int[] a = new int[c.length];
    System.arraycopy(c, 0, a, 0, c.length);
    combos.add(a);
}

【讨论】:

  • 正如我在其中一个 cmets 中已经提到的,这是针对此特定输入的。如果输入大小很大怎么办?
  • 您可以将任何内容传递给generate 方法,它会起作用。自己试试吧。
  • 所有这些工作:generate(new int[][]{{1,3,5},{2,6,7}}); generate(new int[][]{{1,3,5},{2,6,7},{8,9,0}}); generate(new int[][]{{1,3,5,7},{2,6,7,1},{8,9,0,9}}); generate(new int[][]{{1,3,5,7},{2,6,7,1},{8,9,0,9},{16,7,8,10}});
【解决方案2】:

递归解决方案如下所示:

printPermutations(String head, Matrix m)
  if m is empty print head and return
  else for each item in last row of m
    printPermutations(head + item, m - bottom row)

这里的“head”是我们迄今为止所做的所有工作。在递归方法的主体中,必须至少有两种选择,一种输出结果并结束递归,另一种更深入。对于更深层次的替代方案,我们将选定的元素转移到head,删除最下面一行,因为我们不能从任何一行中选择多个项目,然后再做一次。

做得好,递归解决方案通常比使用循环更简单、更简洁。另一方面,递归往往会使用更多的内存

【讨论】:

    猜你喜欢
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 2015-07-21
    • 1970-01-01
    • 2016-03-10
    • 2012-10-01
    • 1970-01-01
    相关资源
    最近更新 更多