import java.util.Stack;
/**
* 数学排列公式工具类
*/
public class ArrangementUtil {
public static Stack<Integer> stack = new Stack<Integer>();
private static int count = 0;
public static void main(String[] args) {
int array[] = {1, 2, 3, 4};
combine(array, 3, 0, 0); // 从这个数组4个数中选择三个
System.out.println("组合次数:" + ArrangementUtil.count);
}
/**
* @param array 元素
* @param toPickNum 要选多少个元素
* @param selectedNum 当前有多少个元素
* @param currentIndex 当前选到的下标
*/
private static void combine(int[] array, int toPickNum, int selectedNum, int currentIndex) {
if (selectedNum == toPickNum) {
System.out.println(stack);
ArrangementUtil.count++;
return;
}
for (int i = currentIndex; i < array.length; i++) {
if (!stack.contains(array[i])) {
stack.add(array[i]);
combine(array, toPickNum, selectedNum + 1, 0);
stack.pop();
}
}
}
}
=========================
import java.util.Stack;
/**
* 数学组合公式工具类
*/
public class CombinationUtil {
public static Stack<Integer> stack = new Stack<Integer>();
private static int count = 0;
public static void main(String[] args) {
int array[] = {1, 2, 3, 4, 5};
// int array[] = {1, 2, 3, 4};
combine(array, 3, 0, 0); // 从这个数组5个数中选择三个
System.out.println("组合次数:" + CombinationUtil.count);
}
/**
* @param array 元素
* @param toPickNum 要选多少个元素
* @param selectedNum 当前有多少个元素
* @param currentIndex 当前选到的下标
*/
private static void combine(int[] array, int toPickNum, int selectedNum, int currentIndex) {
if (selectedNum == toPickNum) {
System.out.println(stack);
CombinationUtil.count++;
return;
}
for (int i = currentIndex; i < array.length; i++) {
if (!stack.contains(array[i])) {
stack.add(array[i]);
combine(array, toPickNum, selectedNum + 1, i);// 和排列公式唯一的的区别在于此处,排列算法此处的i为0,因为排列是有序的
stack.pop();
}
}
}
}
=================================================================================================================
第一个问题:
首先,先让我们来看第一个问题, 有1,2,3,4这4个数字.可以重复的在里面选4次,问能得到多少种结果.easy
1 1 1 1
1 1 1 2
1 1 1 3
1 1 1 4
1 1 2 1
1 1 2 2
.......
4 4 4 3
4 4 4 4
代码实现其实也很简单,大家可以看下代码,理解一下,再自己敲一下,应该可以很快敲出来
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import java.util.Stack;
public class Main {
public static Stack<Integer> stack = new Stack<Integer>();
public static void main(String[] args) {
int shu[] = {1,2,3,4};
f(shu,4,0);
}
/**
*
* @param shu 待选择的数组
* @param targ 要选择多少个次
* @param cur 当前选择的是第几次
*/
private static void f(int[] shu, int targ, int cur) {
// TODO Auto-generated method stub
if(cur == targ) {
System.out.println(stack);
return;
}
for(int i=0;i<shu.length;i++) {
stack.add(shu[i]);
f(shu, targ, cur+1);
stack.pop();
}
}
} |
输出:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[1, 1, 1, 1][1, 1, 1, 2][1, 1, 1, 3][1, 1, 1, 4][1, 1, 2, 1][1, 1, 2, 2]........................[4, 4, 3, 2][4, 4, 3, 3][4, 4, 3, 4][4, 4, 4, 1][4, 4, 4, 2][4, 4, 4, 3][4, 4, 4, 4] |
得到了想要的结果,此处结果又很多种4*4*4*4 = 256种结果。
第二个问题:
同理, 问题来了,这时候有点排列组合的意思了 1,2,3,4排列要的到的是
|
1
2
3
4
5
6
7
|
1 2 3 4
1 2 4 3
1 3 4 2
1 3 2 4
......4 2 1 2
4 3 2 1
|
有没有发现要的到排列的情况,这里stack里的元素是1,2,3,4都不能重复
那么我在入栈的时候加个判断,如果比如1,已经在stack里面了,就不加进去,就不会得到 1 1 1 1 ...的情况了,就得到了排列
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
import java.util.Stack;
public class Main {
public static Stack<Integer> stack = new Stack<Integer>();
public static void main(String[] args) {
int shu[] = {1,2,3,4};
f(shu,4,0);
}
/**
*
* @param shu 待选择的数组
* @param targ 要选择多少个次
* @param cur 当前选择的是第几次
*/
private static void f(int[] shu, int targ, int cur) {
// TODO Auto-generated method stub
if(cur == targ) {
System.out.println(stack);
return;
}
for(int i=0;i<shu.length;i++) {
if(!stack.contains(shu[i])) {
stack.add(shu[i]);
f(shu, targ, cur+1);
stack.pop();
}
}
}
} |
输出:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[1, 2, 3, 4]
[1, 2, 4, 3]
[1, 3, 2, 4]
[1, 3, 4, 2]
[1, 4, 2, 3]
[1, 4, 3, 2]
[2, 1, 3, 4]
[2, 1, 4, 3]
[2, 3, 1, 4]
[2, 3, 4, 1]
[2, 4, 1, 3]
[2, 4, 3, 1]
[3, 1, 2, 4]
[3, 1, 4, 2]
[3, 2, 1, 4]
[3, 2, 4, 1]
[3, 4, 1, 2]
[3, 4, 2, 1]
[4, 1, 2, 3]
[4, 1, 3, 2]
[4, 2, 1, 3]
[4, 2, 3, 1]
[4, 3, 1, 2]
[4, 3, 2, 1]
|
这就是想要的排列结果了.. 4 * 3 * 2 * 1 = 24种结果。
第三个问题:
那么组合问题来了,在1,2,3,4,中选3个有多少种组合方式
|
1
2
3
4
5
6
|
1 2 3
1 2 4
1 3 4
2 3 4
共4种
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
import java.util.Stack;
public class Main {
public static Stack<Integer> stack = new Stack<Integer>();
public static void main(String[] args) {
int shu[] = {1,2,3,4};
f(shu,3,0,0); // 从这个数组4个数中选择三个
}
/**
*
* @param shu 元素
* @param targ 要选多少个元素
* @param has 当前有多少个元素
* @param cur 当前选到的下标
*
* 1 2 3 //开始下标到2
* 1 2 4 //然后从3开始
*/
private static void f(int[] shu, int targ, int has, int cur) {
if(has == targ) {
System.out.println(stack);
return;
}
for(int i=cur;i<shu.length;i++) {
if(!stack.contains(shu[i])) {
stack.add(shu[i]);
f(shu, targ, has+1, i);
stack.pop();
}
}
}
} |
输出:
|
1
2
3
4
|
[1, 2, 3]
[1, 2, 4]
[1, 3, 4]
[2, 3, 4]
|