JAVA 算法 回溯

用于求最优解、一组解、求全部解这类问题

从问题的某一种可能出发,搜索从这种情况出发所能达到的所有可能,如果有路可以走下去,就走到下一个状态,继续按照这种规则搜索;当这条路走到“尽头”而没有达到目标状态的时候,在倒回上一个出发点,从另一个可能出发,继续搜索,直到达到目标状态。

回溯与递归的区别

递归是一种算法结构,递归会出现在子程序中自己调用自己或间接地自己调用自己。

回溯是一种算法思想, 从问题的某一种可能出发, 搜索从这种情况出发所能达到的所有可能, 当这一条路走到” 尽头 “的时候, 再倒回出发点, 从另一个可能出发, 继续搜索. 这种不断” 回溯 “寻找解的方法。
通俗点讲回溯就是一种试探,类似于穷举,但回溯有“剪枝”功能,比如求和问题。给定7个数字,1 2 3 4 5 6 7求和等于7的组合,从小到大搜索,选择1+2+3+4 =10>7,已经超过了7,之后的5 6 7就没必要在继续了,这就是一种搜索过程的优化。

原文链接

走迷宫问题

给一迷宫表个和入口位置,找出并打印出从入口到出口的路径
在这里插入图片描述

public class Zoumigong {
    public static void main(String[] args) {
        //小球从(1,1)出发,到达(6,5)结束
        //值为0表示没走过,值为2表示通路,值为3表示走过(测试过),但是不通
        //在走迷宫时,尝试方向 下右上左,走不通,则回溯
        int[][] map=new int[8][7];
        migong(map);
        for (int[] ints : map) {
            for (int anInt : ints) {
                System.out.print(" "+anInt);
            }
            System.out.println();
        }
        setWay(map,1,1);
        System.out.println("走出之后的");
        for (int[] ints : map) {
            for (int anInt : ints) {
                System.out.print(" "+anInt);
            }
            System.out.println();
        }

    }
    //生成地图
    public static void migong(int[][] map){

        //用1当墙
        for (int i = 0; i < 7; i++) {
            map[0][i]=1;
            map[7][i]=1;
        }
        for (int i = 0; i < 8; i++) {
            map[i][6]=1;
            map[i][0]=1;
        }
        //设置挡板
        map[3][1]=1;map[3][2]=1;

    }
    //寻求出路 下右上左
    public  static boolean setWay(int[][] map,int i,int j){
        if (map[6][5]==2){//找到出路
            return true;
        }
        else {
            if(map[i][j]==0){
                map[i][j]=2;//假设为通路上一点
                //按照下右上左开始尝试
                if (setWay(map, i+1,j)){
                    return true;
                }
                else if (setWay(map, i,j+1)){
                    return true;
                }
                else if (setWay(map, i-1,j)){
                    return true;
                }
                else if (setWay(map, i,j-1)){
                    return true;
                }
                else{//说明该点不通
                    map[i][j]=3;
                    return false;
                }
            }
            else {//该点为1,2,3
                return false;
            }

        }
    }
}

八皇后问题
8x8的棋盘 有八个皇后 要求任意两个皇后都不能处于同一行,同一列或同一斜线上,有多少种解法

在这里插入图片描述

//8x8的棋盘 有八个皇后 要求任意两个皇后都不能处于同一行,同一列或同一斜线上(92种结果,判断15720次)
// 使用一维数组:arr[i]=val  表示第i+1个皇后要放在第i+1行的第val+1列,
public class bahuanghou {
    public static void main(String[] args) {
        Queue8 queue8 = new Queue8();
        queue8.check(0);
        System.out.println(queue8.count);
        System.out.println(queue8.panduancount);
    }
}
class Queue8{
    int max=8;
    int[] array=new int[max];
     int count=0;
    int panduancount=0;
    //check每一次递归时,都有八次循环,循环结束,回溯到上层
    public void check(int n){//放置第n个皇后
        if(n==max){//8个都放置完毕
            print();
            return;
        }
        //
        for (int i = 0; i < max; i++) {
            array[n]=i;
            if(panduan(n)){//判断位置是否冲突
                check(n+1);//摆放下一个
            }
            //冲突就进入下一次循环,相当于把列后移了一次
        }
    }
    public  boolean panduan(int n){//n为第n个皇后
        panduancount++;
        for (int i = 0; i < n; i++) {//i,n不同 皇后不可能同行
            //不同列+不同斜线(y=x;y=-x)
            if(array[i]==array[n]||(Math.abs(array[i]-array[n])==Math.abs(i-n))) {
                return false ;
            }
        }
        return true;
    }
    public void print(){
        count++;
        System.out.println(Arrays.toString(array));
        System.out.println();
    }
}
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值