您的位置:首页 > 编程语言 > Java开发

Java解决排列组合问题——深度优先遍历

2018-03-15 23:05 423 查看
[b]问题1:
[/b]假设袋子里有编号为1,2,...,m这m个球。现在每次从袋子中取一个球几下编号,放回袋中再取,取n次作为一组,枚举所有可能的情况。
分析:每一次取都有m种可能的情况,因此一共有

种情况。
这里我们取m = 3, n = 4,则有

种不同的情况。

代码:
import java.util.Stack;

public class Test {
static int cnt = 0;
static Stack<Integer> s = new Stack<Integer>();

/**
* 递归方法,当实际选取的小球数目与要求选取的小球数目相同时,跳出递归
* @param minv - 小球编号的最小值
* @param maxv - 小球编号的最大值
* @param curnum - 当前已经确定的小球的个数
* @param maxnum - 要选取的小球的数目
*/
public static void kase1(int minv,int maxv,int curnum, int maxnum){
if(curnum == maxnum){
cnt++;
System.out.println(s);
return;
}

for(int i = minv; i <= maxv; i++){
s.push(i);
kase1(minv, maxv, curnum+1, maxnum);
s.pop();
}
}

public static void main(String[] args){
kase1(1, 3, 0, 4);
System.out.println(cnt);
}
}

输出:
[1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 1, 3]
[1, 1, 2, 1]
[1, 1, 2, 2]
[1, 1, 2, 3]
[1, 1, 3, 1]
[1, 1, 3, 2]
[1, 1, 3, 3]
[1, 2, 1, 1]
[1, 2, 1, 2]
[1, 2, 1, 3]
[1, 2, 2, 1]
[1, 2, 2, 2]
[1, 2, 2, 3]
[1, 2, 3, 1]
[1, 2, 3, 2]
[1, 2, 3, 3]
[1, 3, 1, 1]
[1, 3, 1, 2]
[1, 3, 1, 3]
[1, 3, 2, 1]
[1, 3, 2, 2]
[1, 3, 2, 3]
[1, 3, 3, 1]
[1, 3, 3, 2]
[1, 3, 3, 3]
[2, 1, 1, 1]
[2, 1, 1, 2]
[2, 1, 1, 3]
[2, 1, 2, 1]
[2, 1, 2, 2]
[2, 1, 2, 3]
[2, 1, 3, 1]
[2, 1, 3, 2]
[2, 1, 3, 3]
[2, 2, 1, 1]
[2, 2, 1, 2]
[2, 2, 1, 3]
[2, 2, 2, 1]
[2, 2, 2, 2]
[2, 2, 2, 3]
[2, 2, 3, 1]
[2, 2, 3, 2]
[2, 2, 3, 3]
[2, 3, 1, 1]
[2, 3, 1, 2]
[2, 3, 1, 3]
[2, 3, 2, 1]
[2, 3, 2, 2]
[2, 3, 2, 3]
[2, 3, 3, 1]
[2, 3, 3, 2]
[2, 3, 3, 3]
[3, 1, 1, 1]
[3, 1, 1, 2]
[3, 1, 1, 3]
[3, 1, 2, 1]
[3, 1, 2, 2]
[3, 1, 2, 3]
[3, 1, 3, 1]
[3, 1, 3, 2]
[3, 1, 3, 3]
[3, 2, 1, 1]
[3, 2, 1, 2]
[3, 2, 1, 3]
[3, 2, 2, 1]
[3, 2, 2, 2]
[3, 2, 2, 3]
[3, 2, 3, 1]
[3, 2, 3, 2]
[3, 2, 3, 3]
[3, 3, 1, 1]
[3, 3, 1, 2]
[3, 3, 1, 3]
[3, 3, 2, 1]
[3, 3, 2, 2]
[3, 3, 2, 3]
[3, 3, 3, 1]
[3, 3, 3, 2]
[3, 3, 3, 3]
81


问题2:                                                                                                                                                                        
假设袋子里有编号为1,2,...,m这m个球。先后从袋子中取出n个球,依次记录编号,枚举所有可能的情况。
分析:这是排列问题,应该有

种情况。
这里取m = 5, n = 3,


和问题1相比,唯一的区别是排列中不可以有重复。因此开了used数组用以标记是否已经访问。

代码:
import java.util.Stack;

public class Test {
static int cnt = 0;
static Stack<Integer> s = new Stack<Integer>();
static boolean[] used = new boolean[10000];

/**
* 递归方法,当实际选取的小球数目与要求选取的小球数目相同时,跳出递归
* @param minv - 小球编号的最小值
* @param maxv - 小球编号的最大值
* @param curnum - 当前已经确定的小球的个数
* @param maxnum - 要选取的小球的数目
*/
public static void kase2(int minv,int maxv,int curnum, int maxnum){
if(curnum == maxnum){
cnt++;
System.out.println(s);
return;
}

for(int i = minv; i <= maxv; i++){
if(!used[i]){
s.push(i);
used[i] = true;
kase2(minv, maxv, curnum+1, maxnum);
s.pop();
used[i] = false;
}
}
}

public static void main(String[] args){
kase2(1, 5, 0, 3);
System.out.println(cnt);
}
}

输出:
[1, 2, 3]
[1, 2, 4]
[1, 2, 5]
[1, 3, 2]
[1, 3, 4]
[1, 3, 5]
[1, 4, 2]
[1, 4, 3]
[1, 4, 5]
[1, 5, 2]
[1, 5, 3]
[1, 5, 4]
[2, 1, 3]
[2, 1, 4]
[2, 1, 5]
[2, 3, 1]
[2, 3, 4]
[2, 3, 5]
[2, 4, 1]
[2, 4, 3]
[2, 4, 5]
[2, 5, 1]
[2, 5, 3]
[2, 5, 4]
[3, 1, 2]
[3, 1, 4]
[3, 1, 5]
[3, 2, 1]
[3, 2, 4]
[3, 2, 5]
[3, 4, 1]
[3, 4, 2]
[3, 4, 5]
[3, 5, 1]
[3, 5, 2]
[3, 5, 4]
[4, 1, 2]
[4, 1, 3]
[4, 1, 5]
[4, 2, 1]
[4, 2, 3]
[4, 2, 5]
[4, 3, 1]
[4, 3, 2]
[4, 3, 5]
[4, 5, 1]
[4, 5, 2]
[4, 5, 3]
[5, 1, 2]
[5, 1, 3]
[5, 1, 4]
[5, 2, 1]
[5, 2, 3]
[5, 2, 4]
[5, 3, 1]
[5, 3, 2]
[5, 3, 4]
[5, 4, 1]
[5, 4, 2]
[5, 4, 3]
60


问题3:                                                                                                                                                                        从m个球里(编号为1,2,3...,m)一次取n个球,其中m>n,记录取出球的编号,枚举所有的可能性。
分析:这是组合问题。因该有

种可能性。
这里,我们取m = 8, n = 4. 因此有

种可能。

代码:
import java.util.Stack;

public class Test {
static int cnt = 0;
static Stack<Integer> s = new Stack<Integer>();

/**
* 递归方法,当前已抽取的小球个数与要求抽取小球个数相同时,退出递归
* @param curnum - 当前已经抓取的小球数目
* @param curmaxv - 当前已经抓取小球中最大的编号
* @param maxnum - 需要抓取小球的数目
* @param maxv - 待抓取小球中最大的编号
*/
public static void kase3(int curnum, int curmaxv,  int maxnum, int maxv){
if(curnum == maxnum){
cnt++;
System.out.println(s);
return;
}

for(int i = curmaxv + 1; i <= maxv; i++){ // i <= maxv - maxnum + curnum + 1
s.push(i);
kase3(curnum + 1, i, maxnum, maxv);
s.pop();
}
}

public static void main(String[] args){
kase3(0, 0, 4, 8);
System.out.println(cnt);
}
}

输出:
[1, 2, 3, 4]
[1, 2, 3, 5]
[1, 2, 3, 6]
[1, 2, 3, 7]
[1, 2, 3, 8]
[1, 2, 4, 5]
[1, 2, 4, 6]
[1, 2, 4, 7]
[1, 2, 4, 8]
[1, 2, 5, 6]
[1, 2, 5, 7]
[1, 2, 5, 8]
[1, 2, 6, 7]
[1, 2, 6, 8]
[1, 2, 7, 8]
[1, 3, 4, 5]
[1, 3, 4, 6]
[1, 3, 4, 7]
[1, 3, 4, 8]
[1, 3, 5, 6]
[1, 3, 5, 7]
[1, 3, 5, 8]
[1, 3, 6, 7]
[1, 3, 6, 8]
[1, 3, 7, 8]
[1, 4, 5, 6]
[1, 4, 5, 7]
[1, 4, 5, 8]
[1, 4, 6, 7]
[1, 4, 6, 8]
[1, 4, 7, 8]
[1, 5, 6, 7]
[1, 5, 6, 8]
[1, 5, 7, 8]
[1, 6, 7, 8]
[2, 3, 4, 5]
[2, 3, 4, 6]
[2, 3, 4, 7]
[2, 3, 4, 8]
[2, 3, 5, 6]
[2, 3, 5, 7]
[2, 3, 5, 8]
[2, 3, 6, 7]
[2, 3, 6, 8]
[2, 3, 7, 8]
[2, 4, 5, 6]
[2, 4, 5, 7]
[2, 4, 5, 8]
[2, 4, 6, 7]
[2, 4, 6, 8]
[2, 4, 7, 8]
[2, 5, 6, 7]
[2, 5, 6, 8]
[2, 5, 7, 8]
[2, 6, 7, 8]
[3, 4, 5, 6]
[3, 4, 5, 7]
[3, 4, 5, 8]
[3, 4, 6, 7]
[3, 4, 6, 8]
[3, 4, 7, 8]
[3, 5, 6, 7]
[3, 5, 6, 8]
[3, 5, 7, 8]
[3, 6, 7, 8]
[4, 5, 6, 7]
[4, 5, 6, 8]
[4, 5, 7, 8]
[4, 6, 7, 8]
[5, 6, 7, 8]
70
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息