【问题标题】:Getting ALL permutations of ALL sublists of a list of integers获取整数列表的所有子列表的所有排列
【发布时间】:2015-06-29 20:25:17
【问题描述】:

我一直遇到这个问题。基本上,我有一个整数列表,例如

list = [1, 2, 3]

我想获得每个子集的所有可能排列。我知道网上也有类似的问题,但我找不到一个既能处理所有排列又能处理每个子集的问题。换句话说,我想要:

function(list) = 
[], [1], [2], [3],
[1, 2], [2, 1], [1, 3], [3,1], [2, 3], [3,2],
[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]

我知道即使输入列表很小,输出也会变得非常大。不幸的是,我只是不知道如何解决这样的问题。

谢谢!

【问题讨论】:

  • 您似乎已经在您发布的示例中找到了自己问题的答案。为什么你不能写下你所采取的步骤列表并称之为算法?
  • 因为我不是一个聪明人。 :(
  • 更具体地说,我无法将其转换为 java 代码,因为我不确定自己在做什么......

标签: algorithm set combinations


【解决方案1】:
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;

public class Test {

private static boolean[] used;
private static int[] a;

private static void f(int curCount,int subsetSize,ArrayDeque<Integer> perm){
   // System.out.println("in rec "+curCount+" "+subsetSize);
    if(curCount < subsetSize){
        for(int i=0;i<a.length;i++) {
            if (!used[i]) { // try to add i-th elem of array  as a next element of  permutation if it's not busy
                perm.add(a[i]);
                used[i] = true; //mark i-th element as used for  future recursion calls
                f(curCount + 1, subsetSize,perm); // curCount+1 because we added elem to perm. subsetSize is const and it's needed just for recursion exit condition
                used[i] = false; // "free" i-th element
                perm.removeLast();
            }
        }
    }
    else{ //some permutation of array subset with size=subsetSize generated
        for(Integer xx:perm) System.out.print(xx+" ");
        System.out.println();

    }
}

public static void main(String[] args){

  a = new int[]{1,2,3};
  used = new boolean[a.length];
  Arrays.fill(used, false);

  // second param is a subset size (all sizes from 1 to n)
  // first param is number of "collected" numbers, when collected numbers==required subset size (firstparam==second param) exit from recursion (from some particular call-chain)
  // third param is data structure for constructing permutation
  for(int i=1;i<=a.length;i++)f(0,i,new ArrayDeque<Integer>());

} //end of main

} //end of class

输出

1
2
3
1 2
1 3
2 1
2 3
3 1
3 2
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

【讨论】:

  • 一个小问题,很容易纠正:OP 在寻找的函数的输出中包含了空集。
  • @HighPerformanceMark,而不是for(int i=1;i&lt;=a.length;i++)f(0,i,new ArrayDeque&lt;Integer&gt;());,他可以写for(int i=0;i&lt;=a.length;i++)。只需将空列表手动添加到任何输出就更简单了。
【解决方案2】:

所以您正在寻找的是Power Set 的所有可能排列。

This 似乎深入探讨了执行此操作的策略。

【讨论】:

    【解决方案3】:

    如果您的 N 个元素的列表很长,您希望获得 M 所采用的 N 的所有组合,其中 M 介于 1 和 N 之间。对于每个组合,您希望获得所有排列。您可能可以通过 google 找出组合和排列的算法。

    【讨论】:

      【解决方案4】:

      我最终使用了这两个功能的组合。不确定它是否按预期工作,但到目前为止它一直正常工作。

      // Generates all permutations of a set. Thus, given an input like [1, 2, 3] it changes the null
      // final_list input to be [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
      static void heappermute(List<List<Integer>> waypoints, int n,     List<List<List<Integer>>> final_list) {
          int i;
          if (n == 1) {
              final_list.add(waypoints);
          }
          else {
              for (i = 0; i < n; i++) {
                  heappermute(waypoints, n-1, final_list);
                  if (n % 2 == 1) {
                      swap(waypoints.get(0), waypoints.get(n-1));
              }
                  else {
                      swap(waypoints.get(i), waypoints.get(n-1));
                  }
              }
          }
      }
      
      static void swap (List<Integer> x, List<Integer> y)
      {
          List<Integer> temp = new ArrayList<>();
          temp = x;
          x = y;
          y = temp;
      }
      
      
      // Generates all subsets of a given set. Thus, given a list of waypoints, it will return a list of 
      // waypoint lists, each of which is a subset of the original list of waypoints.
      // Ex: Input originalSet = {1, 2, 3}
      //     Output: = {}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}
      // Code modified from http://stackoverflow.com/questions/4640034/calculating-all-of-the-subsets-of-a-set-of-numbers 
      
      public static List<List<List<Integer>>> powerSet(List<List<Integer>> originalSet) {
          List<List<List<Integer>>> sets = new ArrayList<>();
          if (originalSet.isEmpty()) {
              sets.add(new ArrayList<List<Integer>>());
              return sets;
          }
          List<List<Integer>> list = new ArrayList<List<Integer>>(originalSet);
          List<Integer> head = list.get(0);
          List<List<Integer>> rest = new ArrayList<List<Integer>>(list.subList(1, list.size()));
          for (List<List<Integer>> set : powerSet(rest)) {
              List<List<Integer>> newSet = new ArrayList<List<Integer>>();
              newSet.add(head);
              newSet.addAll(set);
              sets.add(newSet);
              sets.add(set);
          }
          return sets;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-18
        • 2017-02-27
        • 2019-08-04
        • 1970-01-01
        • 1970-01-01
        • 2018-09-05
        • 1970-01-01
        • 2013-02-15
        相关资源
        最近更新 更多