组合排列
/**
** 最简单的暴力排列
*/
public static void main(String[] args) {
for (int i = 1; i < 5; i++) {
for (int j = 1; j < 5; j++) {
for (int k = 1; k < 5; k++) {
for (int l = 1; l < 5; l++) {
if(i!=j && i!=k && i!=l && j!=k &&
j!=l && k!=l){
System.err.println(""+i+j+k+l);
}
}
}
}
}
}
/****
* 变化为递归型 #### 记住3个步骤就记住了回溯算法
* 1 递归最后一步 from ==to 即是组合完成形态 (题型组合后的条件判断)
* 2 尝试交换形态 尝试递归
* 3 还原形态 进行下次尝试
**/
public static void main(String[] args) {
final char arr [] = { '1','2','3','4'};
s(arr,0 , arr.length-1);
}
private static void s(char[] arr, int from , int to) {
if(from == to){ //1.最后一步成递归的形态
System.out.println(String.valueOf(arr));
}else {
char ch;
for (int i = from; i <=to ; i++) {
ch=arr[from]; //2.尝试交换不同组合形态
arr[from] = arr[i];
arr[i]=ch;
s(arr,from+1 ,to); //递归不断尝试不同组合形态
ch=arr[from]; // 3 .回溯原来形态 尝试之后还原形态
arr[from] = arr[i];
arr[i]=ch;
}
}
}
-
尝试 xxx + xxx = xxx 且 x ∈ {1,2,3,4,5,6,7,8,9} 并且组合中不能重复
/**
* 借上递归思路
*/
public static void main(String[] args) {
final int array[] = {1,2,3,4,5,6,7,8,9};
retrospective(array,0,array.length-1);
}
public static void retrospective(int[] array, int from, int to){
if(from==to){
if(array[0]*100+array[1]*10+array[2]+
array[3]*100+array[4]*10+array[5] ==
array[6]*100+array[7]*10 + array[8]){ //遍历满足条件形态可能的组合
System.err.println(""+array[0] + array[1]+
array[2]+"+" +array[3]+array[4] + array[5] +"="+
array[6] + array[7] + array[8]);
}
}else { //如上一样尝试不同形态组合
for (int i = from; i < to; i++) {
int t = 0;
t = array[i];
array[i] = array[from];
array[from] = t;
retrospective(array,from+1,to);
t = array[i];
array[i] = array[from];
array[from] = t;
}i
}
}
|
0 |
1 |
2 |
3 |
0 |
? |
|
? |
|
1 |
|
|
|
|
2 |
|
? |
|
|
3 |
|
|
? |
|
4 |
|
? |
|
|
5 |
|
|
|
? |
public static void main(String[] args) {
final int map [] [] = {
{0,0,2,0},
{0,0,0,0},
{0,2,0,0},
{0,0,2,0},
{0,0,0,0}
}; //列出地图
final Collection alreadyPath = new LinkedList(); //路径记录
final Point start = new Point(0,0); //起始位置
alreadyPath.add(start); //添加到记录中
dfs(alreadyPath,map,start.getX(),start.getY());
}
private static void dfs(final Collection alreadyPath,final int[][] map,
int positionX, int positionY) {
final int endX = map.length-1; //终点X坐标
final int endY = map[0].length-1; //终点Y坐标
if(endX==positionX && positionY ==endY){ //满足条件 如上的from==to
System.err.println(alreadyPath);
System.err.println(alreadyPath.size());
}else {
// 右下左上 如上排列组合尝试步骤
final int stepEnum [][] = {{0,1},{1,0},{0,-1} ,{-1,0}};
int nextStepX=0;
int nextStepY=0; //下一步坐标
for (int i = 0; i < stepEnum.length; i++) { //尝试上下作用步骤
nextStepX = positionX + stepEnum[i][0];
nextStepY = positionY + stepEnum[i][1];
if(endX
/******
****
**/
public static void main(String[] args) {
final int bfsMap [] [] = {
{0,0,2,0},
{0,0,0,0},
{0,2,0,0},
{0,0,2,0},
{0,0,0,0}
}; //地图
int head = 0,tail=1; //head指向第一步的所有以下步骤
int nextStepX=-1,nextStepY=-1; //继续下一步的临时变量
final int endX = bfsMap.length-1; //终点X坐标
final int endY = bfsMap[0].length-1; //终点Y坐标
final Collection alreadyPath = new LinkedList(); //路径记录 保证不回头 避免循环
final List queue = new ArrayList(1000); //储存所有可行步骤
Point2 start = new Point2(0, 0, 0,-1); //起点位置 00 XY 0标识第一步 -1 记录上一步所在索引 因为第一步索引-1结束条件
queue.add(start);
alreadyPath.add(start); //记录
final int stepEnum [][] = {{0,1},{1,0},{0,-1} ,{-1,0}}; //模拟不走
while (head