暴力枚举算法篇

组合排列

  • 组合排列 所有从 1-4 出现的情况

/**
**  最简单的暴力排列
*/
 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
        }
    }
  • DFS( 深度优先搜索)

0123
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<Point> alreadyPath = new LinkedList<Point>();  //路径记录
        final Point start = new Point(0,0);    //起始位置
        alreadyPath.add(start);  //添加到记录中
        dfs(alreadyPath,map,start.getX(),start.getY());
    }

    private static void dfs(final Collection<Point> 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<nextStepX || endY<nextStepY
                        ||nextStepX<0 || nextStepY<0){  //地图边界限定条件
                    continue;
                }
                Point point = new Point(nextStepX, nextStepY);
                //如果路径中包含点  说明走过的路不再尝试
                if(!alreadyPath.contains(point)&&map[nextStepX][nextStepY]==0){
                    alreadyPath.add(point);   //如果满足条件添加到队列
                    dfs(alreadyPath,map,nextStepX,nextStepY);    
                    alreadyPath.remove(point);    //尝试回溯
                }
            }
        }
    }

/****
****point
*****/
@ToString
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Point {
    private int x;
    private int y;
}


  • BFS (广度优先搜索)

/******
**** 
**/

  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<Point2> alreadyPath = new LinkedList();  //路径记录  保证不回头  避免循环
        final List<Point2> 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<tail){    //如果条件结束  说明走不到终点则自然中断
            for (int i = 0; i < stepEnum.length; i++) {     
                nextStepX = queue.get(head).getX()+stepEnum[i][0];
                nextStepY = queue.get(head).getY()+stepEnum[i][1];
                if(endX<nextStepX || endY<nextStepY ||nextStepX<0 || nextStepY<0){  //地图的边界条件
                    continue;
                }
                Point2 point = new Point2(nextStepX, nextStepY, queue.get(head).getStep()+1,head);
                //如果回路中不包含  并且不是樯   记录下来算作可行步骤
                if(!alreadyPath.contains(point)&&bfsMap[nextStepX][nextStepY]==0){
                    alreadyPath.add(point);
                    queue.add(point);
                    tail++;
                }
                //终点条件  遍历出步数结果
                if(nextStepX==endX && nextStepY == endY){
                    Point2 temp = queue.get(tail-1);
                    while (true){
                        System.err.println(temp);
                        temp = queue.get(temp.getPreIndex());
                        if(temp.getPreIndex()==-1){
                            System.err.println(temp);
                            return;
                        }
                    }
                }
            }
            head++;   //模拟的部署完成  可以进行下个队列的所有可行步骤

        }

    }
/***
**   POINT      记录部署和上一个步骤
**/
@NoArgsConstructor
@AllArgsConstructor()
@Data
@EqualsAndHashCode(exclude ={"step","preIndex"} )
public class Point2{
    private int x;
    private int y;
    private int step;        //步数
    private int preIndex;   //上一步的位置的索引

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值