我完全迷失了。我可以迭代地执行此操作,但递归对我来说是新的。如果给我一个内部有1,2,3的arraylist,那么带有重复的总可能组合是27。
111,112,113,121,122,123等......
我如何递归地找到它?我会展示我的代码,但我甚至没有接近这个概念......
答案 0 :(得分:3)
您可以使用此概念并制作自己的递归函数。 使用它你可以得到所有可能的组合。
答案 1 :(得分:1)
如果更改了ArrayList的大小,那么解决方案怎么样?
public static void main(String args[]) {
ArrayList<Integer> ali = new ArrayList<>();
ali.add(1);
ali.add(2);
ali.add(3);
System.out.println(combinations(ali).toString().replace("], [", "],\n ["));
}
这在开始时只是一点帮助。
public static List<List<Integer>> combinations(List<Integer> input) {
return step(input, input.size(), new ArrayList<>());
}
这是递归方法,
public static List<List<Integer>> step(List<Integer> input,
int k,
List<List<Integer>> result) {
// We're done
if (k == 0) {
return result;
}
// Start with [[1], [2], [3]] in result
if (result.size() == 0) {
for (Integer i : input) {
ArrayList<Integer> subList = new ArrayList<>();
subList.add(i);
result.add(subList);
}
// Around we go again.
return step(input, k - 1, result);
}
// Cross result with input. Taking us to 2 entries per sub list. Then 3. Then...
List<List<Integer>> newResult = new ArrayList<>();
for (List<Integer> subList : result) {
for(Integer i : input) {
List<Integer> newSubList = new ArrayList<>();
newSubList.addAll(subList);
newSubList.add(i);
newResult.add(newSubList);
}
}
// Around we go again.
return step(input, k - 1, newResult);
}
输出:
[[1, 1, 1],
[1, 1, 2],
[1, 1, 3],
[1, 2, 1],
[1, 2, 2],
[1, 2, 3],
[1, 3, 1],
[1, 3, 2],
[1, 3, 3],
[2, 1, 1],
[2, 1, 2],
[2, 1, 3],
[2, 2, 1],
[2, 2, 2],
[2, 2, 3],
[2, 3, 1],
[2, 3, 2],
[2, 3, 3],
[3, 1, 1],
[3, 1, 2],
[3, 1, 3],
[3, 2, 1],
[3, 2, 2],
[3, 2, 3],
[3, 3, 1],
[3, 3, 2],
[3, 3, 3]]
答案 2 :(得分:0)
这是我刚刚在python中制作的硬编码解决方案,但它应该证明原理:
def combinations(original,indexes):
indexes[2] = indexes[2] + 1
if(indexes[2] == 3):
indexes[1] = indexes[1] + 1
indexes[2] = 0
if(indexes[1] == 3):
indexes[0] = indexes[0] + 1
indexes[1] = 0
if(indexes[0] != 3):
print str(original[indexes[0]]) + str(original[indexes[1]]) \
+ str(original[indexes[2]])
combinations(original, indexes)
combinations([1,2,3],[0,0,0])
注意我是如何使用函数组合()的。此函数将原始数组作为参数,将第二个数组作为跟踪索引。
当我调用该函数启动它时,我将索引数组初始化为全0。
在堆栈中的每个函数中,您应该增加索引数组中的索引以生成正确的输出。注意在我的解决方案中我如何使用三个if语句,这是硬编码部分。这可能是通过for循环完成的。
最后,使用修改后的索引数组再次调用combination()函数内部函数(递归),直到满足end子句(第一个索引已经超出)。
此代码段应作为指导,因为我看到您标记为java
答案 3 :(得分:0)
这是java中的方法:
String combine(ArrayList<Integer> a, String b){
String c="";
if(b.length()==a.size()){
System.out.println(b); //found a combo
return "";
}
//append characters to string b
for(int x=0;x<a.size();x++){
c=b+((Integer)a.get(x)).intValue();
c+=combine(a,c);
}
return c;
}
在循环的每次迭代中,它会将一个字符附加到arraylist a中的字符串b并递归调用自身。一旦字符串b的长度达到3(即arraylist a的大小),就意味着生成了一个组合并显示了它。此方法适用于任何大小的arraylist。
答案 4 :(得分:0)
我理解你的斗争。在跟踪所有调用并决定如何导航问题时,递归地解决问题通常很棘手。经过一番思考后,我能够解决这个问题,使用int数组表示排列,使用ArrayList进行存储。 没有使用循环,也没有检查重复。
我编写了一个名为getPermutations的易于调用的方法,它允许您使用整数[1,n]查找长度为n的所有排列。此方法调用实际的递归方法,这有点复杂。在解决这样的问题时,使用方法的参数来跟踪某些数据点很重要,但这会使实际调用方法有点痛苦(因此使用辅助方法) 。我的代码如下所示。
//Recursive Method
public static ArrayList<int[]> permutationsFrom(int[] start,int i, int val, ArrayList<int[]> prev) {
int n = start.length;
if (i == n) {
final int[] perm = start.clone();
prev.add(perm);
return prev;
}
else if (val > n) {
return prev;
}
else {
int[] next = start.clone();
next[i] = val;
prev.addAll(permutationsFrom(next, i+1, 1, new ArrayList<int[]>()));
return permutationsFrom(next, i, ++val, prev);
}
}
//Invokation
public static ArrayList<int[]> getPermutations(int n) {
return permutationsFrom(new int[n], 0, 1, new ArrayList<int[]>());
}
//Print the results
public static void main(String[] args) {
ArrayList<int[]> perms = getPermutations(3);
System.out.println(perms.size());
for (int[] perm : perms) {
for (int el : perm) {
System.out.print(el + " ");
}
System.out.println();
}
}
递归的工作原理:
从完全“未确定”的排列开始:需要找到每个可能的索引的每个可能值
在当前索引i处,递归地调用捕获每个值val的方法,从1到n
已经找到完整的排列当i == n 时(即每个索引已经从0到n-1确定),因此int数组应该被添加到集合中先前的排列,prev
如果 val&gt; n 索引i处的每个可能值(从1到n)都已被计算,因此可以返回集合(此时方法将继续递增i并水平移动)
答案 5 :(得分:0)
这个派对迟到了,&amp;抱歉,它在c#中,但是嘿,它与Java类似。这里的一切看起来都有点复杂,所以这里的函数非常简单,应该很容易翻译成Java -
public static List<List<T>> Permutations<T>(List<T> list)
{
List<List<T>> result = new List<List<T>>();
for (int i = 0; i < list.Count(); i++)
{
T initialValue = list[i];
List<T> clonedList = list.Where((item, index) => { return index != i; }).ToList(); // proper copy, less the initialValue item
// here's where the recursion happens, but only if there are at least 2 items left in the list
List<List<T>> permutations = clonedList.Count > 0 ? Permutations(clonedList) : new List<List<T>> { new List<T>() };
foreach (List<T> permutation in permutations)
{
List<T> combined = new List<T> { initialValue };
combined.AddRange(permutation);
result.Add(combined);
}
}
return result;
}