回溯算法 - Java实现N皇后问题

回溯算法 - Java实现N皇后问题

1.回溯算法

1.1 回溯算法的介绍

  • 回溯算法实际上一个类似枚举的深度优先搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回(也就是递归返回),尝试别的路径

  • 回溯的处理思想,有点类似枚举(列出所有的情况)搜索。我们枚举所有的解,找到满足期望的解。为了有规律地枚举所有可能的解,避免遗漏和重复,我们把问题求解的过程分为多个阶段。每个阶段,我们都会面对一个岔路口,我们先随意选一条路走,当发现这条路走不通的时候(不符合期望的解),就回退到上一个岔路口,另选一种走法继续走

1.2 N皇后问题的介绍

  • n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击
    在这里插入图片描述

2.Java实现N皇后问题

package com.lagou.backMethod;

/**
 * @author 云梦归遥
 * @date 2022/5/22 9:49
 * @description 回溯算法 - N皇后问题
 */
public class NQueens {
    /**
     * @param n     表示n * n 的格子
     * @param row   当前是多少行
     * @param res   用一个数组,记录每一行的皇后所在的列
     * @param count 结果总数
     * @return
     */
    public int nQueen(int n, int row, int[] res, int count) {
        if (row == n) {
            //打印
            print(n, res);
            count++;
            System.out.println("-----------");
            return count;
        }
        for (int col = 0; col < n; col++) {
            //先尝试着把皇后放在这一列
            res[row] = col;
            //判断和上面行的皇后是否冲突
            if (isOk(row, col, res)) {
                //迭代,下一行
                count = nQueen(n, row + 1, res, count);
            }
        }
        return count;
    }

    private boolean isOk(int row, int col, int[] res) {
        for (int i = 0; i < row; i++) {
            //判断上面每行皇后所在列, 如果和当前列相同则为false
            if (res[i] == col) {
                return false;
            }
            //判断撇和捺方向, 是两个斜率为1和-1的直线, 则他们两个坐标 |y2 - y1| == |x2 - x1|
            if (row - i == col - res[i] || row - i == res[i] - col) {
                return false;
            }
        }
        return true;
    }

    private void print(int n, int[] res) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (res[i] == j) {
                    System.out.print("Q");
                } else {
                    System.out.print("*");
                }
                System.out.print(" ");
            }
            System.out.println();
        }
    }
}

进行测试

package com.lagou.backMethod.test;

import com.lagou.backMethod.NQueens;

/**
 * @author 云梦归遥
 * @date 2022/5/22 11:21
 * @description
 */
public class NQueensTest {
    public static void main(String[] args) {
        NQueens nQueens = new NQueens();
        int n = 8;
        int nQueen = nQueens.nQueen(n, 0, new int[n], 0);
        System.out.println("nQueen = " + nQueen);
    }
}

在这里插入图片描述

3.总结

  • 时间复杂度
    • N皇后问题的时间复杂度为: O(n ! ),实际为 n ! / 2
  • 优缺点
    • 优点:
      • 回溯算法的思想非常简单,大部分情况下,都是用来解决广义的搜索问题,也就是,从一组可能的解中,选择出一个满足要求的解。回溯算法非常适合用递归来实现,在实现的过程中,剪枝操作是提高回溯效率的一种技巧。利用剪枝,我们并不需要穷举搜索所有的情况,从而提高搜索效率
    • 劣势:
      • 效率相对于低(动态规划)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值