Java ArrayList的置换<;整数>;

Java ArrayList的置换<;整数>;,java,arraylist,combinations,permutation,Java,Arraylist,Combinations,Permutation,我正在研究一个问题,在这个问题上,我必须获得一个数字数组列表的所有排列。唯一的限制是任何数字都不能以0开头,因此如果我们有[0,1,2],我们将得到 [1,2,0] [1,0,2] [2,0,1] [2,1,0] 我知道如何使用3个循环来实现这一点,但问题是我必须对不同大小的数字集重复这一点,所以我需要一种方法,我可以应用于不同的数字集,但我不知道如何实现这一点。我想我必须使用某种递归函数,但我不知道如何实现它,所以数字不能以0开头。有什么想法吗?请不要只是张贴代码我想了解的问题,谢谢你的优势

我正在研究一个问题,在这个问题上,我必须获得一个数字数组列表的所有排列。唯一的限制是任何数字都不能以0开头,因此如果我们有[0,1,2],我们将得到

[1,2,0]

[1,0,2]

[2,0,1]

[2,1,0]


我知道如何使用3个循环来实现这一点,但问题是我必须对不同大小的数字集重复这一点,所以我需要一种方法,我可以应用于不同的数字集,但我不知道如何实现这一点。我想我必须使用某种递归函数,但我不知道如何实现它,所以数字不能以0开头。有什么想法吗?请不要只是张贴代码我想了解的问题,谢谢你的优势

您可以按如下所述递归解决此问题:。 唯一缺少的是对零的限制,可以这样解决(循环取自上面的示例):

for(列表al:MyList){
//您需要添加的部分:
if(al.get(0)=0){
继续;
}
字符串appender=“”;
for(整数i:al){
系统输出打印(附录+i);
appender=“”;
}
System.out.println();
}

基本上检查每个排列的第一个元素,并跳过前导为零的元素。
继续
跳到循环的下一个迭代,从而跳到下一个排列。

奇怪的问题!有趣的代码kata

我天真地认为我会有一个递归方法,它需要:

  • 调用者当前选择的项目列表
  • 被调用方可用的一组项
该方法将在集合上迭代以选择另外一个项,并使用该项扩展的列表调用自己,并使用该项缩减集合。返回后,从列表中删除,添加回集合并继续下一个项目(当然,获取集合的防御性副本)

如果当前列表为空,则根据您的规则,选定的第一项不能为0。如果您必须在某个地方收集排列(而不仅仅是打印),则集合或观察者需要第三个参数

当可用集为空时,递归明显停止,此时排列被发送到集合或观察者

如果项目可以重复,您可以先对其进行排序,从而跳过在给定位置再次选择相同项目


注意,对于N个项,这需要N个递归深度。但危险是最小的,因为即使N=10000,也可能不会出现堆栈溢出,但完成的CPU时间是顺序(N!)(可能是世界末日…

共享您的实现(即使它从0开始),因此我们可以帮助您微调它将您的排列(最好使用递归获得)放入ArrayList。在返回ArrayList之前,遍历它并删除任何以0开头的元素。所以我用它来创建所有置换,但我发现了一个问题,即当您给出的列表有许多数字时,这些组合无法存储,程序也无法完成,因为它超出了内存堆,因此,最好是计算一个置换,执行我想执行的操作,并处理该置换,因此我一次只处理一个置换,而不是将所有可能的组合存储在数组中。问题不是将结果存储在数组中,而是递归深度。每次调用函数时,返回地址都被推送到调用堆栈上。这里的问题是,如果您的递归太深,因为您有一个非常大的列表,那么调用堆栈将耗尽空间,您将收到堆栈溢出。您可以使用迭代方法来计算置换,但请记住,计算所有置换都是在O(n!)中进行的,这对于大输入来说不是很有效。
for (List<Integer> al : myLists) {

    // The part you need to add:
    if (al.get(0) == 0) {
        continue;
    }

    String appender = "";
    for (Integer i : al) {
        System.out.print(appender + i);
        appender = " ";
    }
    System.out.println();
}