打印2D矩阵中所有元素的组合

时间:2015-04-27 20:15:52

标签: java algorithm matrix

打印尺寸为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。

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

递归解决方案看起来像这样:

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)

这里&#34;头&#34;是我们迄今为止所做的所有工作。在递归方法的主体中,必须至少有两个选择,一个输出结果并结束递归,另一个更深入。对于更深层的替代方案,我们将所选元素转移到head,删除底行,因为我们无法从任何行中选择多个项目,并再次执行此操作。

做得好,递归解决方案通常比使用循环更简单,更清晰。另一方面,递归倾向于使用更多的内存