首先为什么要写排列组合?因为排列组合在数学中占有重要的地位,其与概率论也有密切关系;并且排列组合问题在求职的笔试,面试出现的概率特别高,而我在网上又没有搜到比较全面题型的文章;同时,我觉得编写排列组合程序对学习递归也是很有帮助的;当然,最重要的原因是排列组合本身就很有趣!所以就总结下排列组合的各种问法,分两篇写:上篇写排列,下篇写组合。
组合篇
排列篇地址:http://blog.youkuaiyun.com/nash_/article/details/8351611
首先从各大IT公司的题中总结出排列组合的对象都是整形数组或字符数组,而且绝大部分组合问题都是无重复数字或者字符的;所以组合问题可以按输入数据分为两大类:输入数据有重复和无重复,又可以按输出数据分为两大类:输出数据有重复和无重复。
由于侧重点在输入数据无重复,所以先看输入数据无重复类型:
1. 从数组a中,取出n个数的所有组合(不可重复取)
如a={1,2,3}。当n=2时候的所有组合数为12,13,23
算法思想:按递增顺序输出,如12,13,14,15.....23.24.25........34,35.............用一个变量begin遍历的第一个数
代码清单:
public class ZuHe {
public void combine(int[] a, int n) {
if(null == a || a.length == 0 || n <= 0 || n > a.length)
return;
int[] b = new int[n];//辅助空间,保存待输出组合数
getCombination(a, n , 0, b, 0);
}
private void getCombination(int[] a, int n, int begin, int[] b, int index) {
if(n == 0){//如果够n个数了,输出b数组
for(int i = 0; i < index; i++){
System.out.print(b[i] + " ");
}
System.out.println();
return;
}
for(int i = begin; i < a.length; i++){
b[index] = a[i];
getCombination(a, n-1, i+1, b, index+1);
}
}
public static void main(String[] args){
ZuHe robot = new ZuHe();
int[] a = {1,2,3,4};
int n = 2;
robot.combine(a,n);
}
}
2.从数组a中,取出n个数的所有组合(可重复取)
如a={1,2,3}。当n=2时候的所有组合数为11,12,13,22,23,33
算法思想:首先对数组a排序,再利用1的算法,把i=begin,改成i=0,让它每次从0开始遍历,但每个组合都是升序排列,所以为了去重加上升序的判断
代码清单:
import java.util.Arrays;
public class ZuHe {
public void combine(int[] a, int n) {
if(null == a || a.length == 0 || n <= 0 || n > a.length)
return;
Arrays.sort(a);
int[] b = new int[n];//辅助空间,保存待输出组合数
getCombination(a, n , 0, b, 0);
}
private void getCombination(int[] a, int n, int begin, int[] b, int index) {
if(n == 0){//如果够n个数了,输出b数组
for(int i = 0; i < index; i++){
System.out.print(b[i] + " ");
}
System.out.println();
return;
}
for(int i = 0; i < a.length; i++){
if(index == 0 || a[i] >= b[index-1]){
b[index] = a[i];
getCombination(a, n-1, i+1, b, index+1);
}
}
}
public static void main(String[] args){
ZuHe robot = new ZuHe();
int[] a = {1,2,3,4};
int n = 3;
robot.combine(a,n);
}
}