获取整数列表的所有子列表的所有排列

时间:2015-06-29 20:25:18

标签: algorithm set combinations

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

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]

我知道即使对于小的输入列表大小,输出也会变得非常大。不幸的是,我无法弄清楚如何解决这个问题。

谢谢!

4 个答案:

答案 0 :(得分: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 2 1 1 3 2 2   
3 2 1

答案 1 :(得分:0)

所以你要找的是Power Set的所有可能的排列。

This似乎深入探讨了实现这一目标的策略。

答案 2 :(得分:0)

如果你的N个元素中的列表很长,你想得到M取的所有N的组合,其中M在1和N之间。对于每个组合,你想得到所有的排列。您可以通过谷歌找出组合和排列的算法。

答案 3 :(得分:0)

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

// 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;
}