每日一省之————递归法计算数组的所有排列组合
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的逻辑,把大的数组化小,得到较小的数组返回的可能的排列组合后,再拼接成较大的数组的排列组合。
上述的分析过程表明可以使用递归的方法进行实现。具体实现代码如下:
算法内部逻辑:模拟人进行排列组合的过程。
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; } }
相关文章推荐
- 每日一道算法题:打印一维数组的所有组合
- N个数组中所有元素的排列组合(笛卡尔积)算法
- javascript数组全排列,数组元素所有组合
- C# 计算排列组合数,及列出所有组合形式的算法
- 列出多个数组所有排列组合
- php求数组全排列,元素所有组合的方法总结
- 排列组合-打印出一个数组的元素的所有排列方式-算法
- N个数组中所有元素的排列组合(笛卡尔积)算法
- 【C++】求数组中所有元素的排列或组合
- php求数组全排列,元素所有组合的方法
- 求数组的所有排列组合数
- 输出数组的所有元素的排列组合(递归)
- php求数组全排列,元素所有组合的方法
- php数组全排列,元素所有组合
- [leetcode 46] Permutations------数组中元素的所有排列组合集合
- 形如数组1223打印所有不同的组合排列java
- 求一个长度为n的数组中长度为m的所有排列组合。
- 求一数组中某一范围内所有组合(不重复)C#
- 输出1,2,2,3,4,5的所有排列组合,4不能在第三位,3和5不能相邻
- 找出数组中满足条件的所有组合!