打印尺寸为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。
答案 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
,删除底行,因为我们无法从任何行中选择多个项目,并再次执行此操作。
做得好,递归解决方案通常比使用循环更简单,更清晰。另一方面,递归倾向于使用更多的内存