我有三角形/树吗?任何大小的M。
在这种情况下,大小M为3:
1
2 3
4 5 6
我的目标是输出所有组合,就像您从上到下遍历一样。结果将是{124} {125} {135} {136}
我如何将for循环与递归结合起来以简化操作
private ArrayList<int[]> listOfCombinations = new ArrayList<int[]>();
public void callSequence(int[] combo, int size, int n) {
for (int i = 0; i < 4 && size >= 3; i++) {
// System.out.println("combinations array :" + combo[0] + combo[1] + combo[2]);
listOfCombinations.add(combo);
listOfCombinations.get(i)[0] = 1;
System.out.print(listOfCombinations.get(i)[0]);
}
System.out.println();
for (int i=0; i < 2; i++) {
listOfCombinations.add(combo);
listOfCombinations.get(i)[1] = 2;
System.out.print(listOfCombinations.get(i)[1]);
}
for (int i=2; i < 4; i++) {
listOfCombinations.add(combo);
listOfCombinations.get(i)[1] = 3;
System.out.print(listOfCombinations.get(i)[1]);
}
System.out.println();
for (int i=4; i<=5; i++) {
listOfCombinations.get(i)[2] = i;
System.out.print(listOfCombinations.get(i)[2]);
}
for (int i=5; i<=6; i++) {
listOfCombinations.get(i)[2] = i;
System.out.print(listOfCombinations.get(i)[2]);
}
当我调用此函数时,它将打印
1 1 1 1
2 2 3 3
4 5 5 6
所以数组是{1,2,4} {1,2,5} {1,3,5} {1,3,6},这是正确的输出,但这是一个不好的方法。我试图考虑如何用递归来做到这一点,以便我可以简化它。
答案 0 :(得分:0)
假设您的数据的行为如下:
RowNum: Position:
0 1
1 2 3
2 4 5 6
然后,您可以利用一个事实,即左边的Position等于其上方的位置加上RowNum,而右边的Position等于其上方的位置加上RowNum加1。因此,您可以构建一个递归算法使用这样的事实:
public static void main(String[] args) {
int maxRows = 3;
paths(maxRows, 1, 1, "1");
}
/**
* Recursive top to bottom depth first approach
*
* @param maxRow Total number of rows to travel down.
* @param rowNum The current row an iteration is on.
* @param position The position number above the current iteration.
* @param values The values so far along the path.
*/
public static void paths(int maxRow, int rowNum, int position, String values) {
//You've hit the bottom so print the results
if(rowNum >= maxRow) {
System.out.println(values);
return;
}
int nextRow = rowNum + 1;
//Calculate position for left side branch, append it to values, and start next iteration
int leftPosition = position + rowNum;
String leftValues = values + " " + leftPosition;
paths(maxRow, nextRow, leftPosition, leftValues);
//Calculate position for right side branch, append it to values, and start next iteration
int rightPosition = position + rowNum + 1;
String rightValues = values + " " + rightPosition;
paths(maxRow, nextRow, rightPosition, rightValues);
}
编辑:这是一个将所有内容存储在容器中的版本,并具有重载版本以简化用户实际需要的参数。
public static void main(String[] args) {
//Initializes the path function
List<List<Integer>> allPaths = paths(4);
System.out.println(allPaths);
}
/**
* Recursively find all paths in a pyramid like node path. Depth first search.
* <pre><code>
* Row Position
* 0 1
* 1 2 3
* 2 4 5 6
* 3 7 8 9 10
* </code></pre>
*
* @param maxDepth Total number of rows to travel down.
* @return Collection of all the paths in their own collections.
*/
public static List<List<Integer>> paths(int maxDepth) {
List<List<Integer>> allPaths = new ArrayList<>();
List<Integer> path = new ArrayList<>();
path.add(1);
paths(maxDepth, 1, 1, path, allPaths);
return allPaths;
}
/**
* Recursively find all paths in a pyramid like node path. Depth first search.
*
* @param maxDepth Total number of rows to travel down.
* @param currentDepth The current depth an iteration is on.
* @param topPosition The position number above the current iteration.
* @param currentPath The values so far along the path.
* @param allPaths Container for all the paths when it reaches the end.
*/
private static void paths(int maxDepth, int currentDepth, int topPosition, List<Integer> currentPath, List<List<Integer>> allPaths) {
//You've hit the bottom so print the results
if(currentDepth >= maxDepth) {
allPaths.add(currentPath);
return;
}
int nextDepth = currentDepth + 1;
//Calculate position for left side branch, append it to values, and start it's branching iterations
int leftPosition = topPosition + currentDepth;
List<Integer> leftArray = new ArrayList<>(currentPath);
leftArray.add(leftPosition);
paths(maxDepth, nextDepth, leftPosition, leftArray, allPaths);
//Calculate position for right side branch, append it to values, and start it's branching iterations
int rightPosition = topPosition + currentDepth + 1;
List<Integer> rightArray = new ArrayList<>(currentPath);
rightArray.add(rightPosition);
paths(maxDepth, nextDepth, rightPosition, rightArray, allPaths);
}
答案 1 :(得分:0)
要注意的是,行n
中节点r
的两个孩子分别是n + r
和n + r + 1
。话虽如此,您可以构建一个相当简单的递归。 (对不起,您必须自己转换为Java!)
const paths = (levels, node = 1, row = 1, res = [[1]]) => levels < 2
? res
: [
... paths (levels - 1, node + row, row + 1, res .map ((path) => [...path, node + row])),
... paths (levels - 1, node + row + 1, row + 1, res .map ((path) => [...path, node + row + 1]))
]
const results = paths (4)
console.log (
results.map (JSON.stringify) .join ('\n')
)
会有2 ^ n
个结果,所以我不想尝试50个级别!
这是一种更简洁的编写递归的方法:
const last = (xs) => xs[xs.length - 1];
const paths = (levels, row = 1, res = [[1]]) => levels < 2
? res
: paths (
levels - 1,
row + 1,
res.flatMap(xs => [[...xs, last(xs) + row], [...xs, last(xs) + row + 1]])
)
const results = paths (4)
console.log (
results.map (JSON.stringify) .join ('\n')
)
这是相同的算法,只是编写递归的一种更简洁的方法。我们接受较深的级别数,然后默认为第一级别的行号(1
)和结果([[1]]
)。递归从级别中减去一个,在行中添加一个,然后通过为该行中的每个条目创建两个条目来计算下一行的结果,其中一个附加最后一个值加行号,另一个附加一个比最后一个值加上行号。这比第一种方法更干净。