您的位置:首页 > 其它

每日一省之————递归法计算数组的所有排列组合

2016-08-14 14:08 288 查看
本算法的目的: 给定一组数字,求这些数字的所有可能的排序组合。

算法内部逻辑:模拟人进行排列组合的过程。

1. 假设仅有2个数字, 则交换其位置,可以得到所有可能的组合,也即2组。

2. 假设有3个数字。则取出第1个数字,将第2和第3个数字交换位置后得到2种组合,然后在每种组合的开头插入第1个数字。得到了3个数字排列组合的其中两种;

然后取出第2个数字,将第1和第3个数字交换位置后得到2种组合,然后在每种组合的开头插入第2个数字。又得到了3个数字排列组合的其中两种

接着取出第3个数字,将第1和第2个数字交换位置后得到2种组合,然后在每种组合的开头插入第3个数字。又得到了3个数字排列组合的其中两种。至此,我们得到了3个数字的所有排列组合(6种)

3. 假设有4个数字。与3个数字一样,依次取出其中的某一个,将剩余的3个进行排列得到6种组合,然后在这6种组合的开头插入一开始取出的那个元素。这样,遍历这4个数字一遍之后,可以得到一共4*6=24种组合。

4. 假设有5个数字,同理:依据步骤2或3或4的逻辑,把大的数组化小,得到较小的数组返回的可能的排列组合后,再拼接成较大的数组的排列组合。

上述的分析过程表明可以使用递归的方法进行实现。具体实现代码如下:

public class Combine {

public static void main(String[] args) {

List<Integer> a = new ArrayList<Integer>(4);
a.add(1);
a.add(2);
a.add(3);
a.add(4);
a.add(5);

int count = 0;

List<List<Integer>> resList = combination(a);
for (List<Integer> intList : resList) {
count++;
for (Integer i : intList) {
System.out.print(i + ", ");
}
System.out.println();
}
System.out.println("一共有 " + count + " 种组合");
}

public static List<List<Integer>> combination(List<Integer> list) {

if (list.size() == 1) {

throw new IllegalArgumentException("the size of list must be lager than one");

}

List<List<Integer>> result = new ArrayList<List<Integer>>();

int size = list.size();

if (size == 2) {

List<Integer> list1 = new ArrayList<>();
list1.add(list.get(0));
list1.add(list.get(1));

List<Integer> list2 = new ArrayList<>();
list2.add(list.get(1));
list2.add(list.get(0));

result.add(list1);
result.add(list2);
} else if (size > 2) {

for (int i = 0; i < list.size(); i++) {

List<Integer> copied = new ArrayList<Integer>(list);
copied.remove(i);
List<List<Integer>> subList = combination(copied);
for (List<Integer> li : subList) {

li.add(0, list.get(i));
result.add(list);
}
}

}

return result;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排列组合