带你轻松拿捏N皇后问题

简介: 要求任何两个皇后不同行、不同列,也不在同一 条斜线上

image.png


第一题:只求摆法有多少种


N皇后问题是指在N*N的棋盘上要摆N个皇后,


要求任何两个皇后不同行、不同列,也不在同一 条斜线上


给定一个整数 n,返回 n 皇后的摆法有多少种。


n=1,返回1


n=2或3,2皇后和3皇后问题无论怎么摆都不行,返回0


n=8,返回 92


public static int num(int n) {
    if (n < 1) return 0;
    int[] record = new int[n];  // 用于记录下过的地方, record[x] = y 表示在 x 行时下的是第 y 列
    return process(record, 0);
}
/**
 * @param record  之前下过的位置
 * @param x  当前来到 x 行
 * @return
 */
public static int process(int[] record, int x) {
    if (x == record.length) return 1;  // 如果 n 个皇后都走完,那么说明找到了一种方法
    int res = 0;
    //尝试把 x 行的皇后放到 y 列
    for (int y = 0; y < record.length; y++) {
        if (isVaild(record, x, y)) {
            record[x] = y;
            res += process(record, x + 1);
        }
    }
    return res;
}
/**
 * @param record
 * @param x 当前所在行
 * @param y 当前所在列
 * @return
 */
public static boolean isVaild(int[] record, int x, int y) {
    for (int i = 0; i < x; i++) {
        // 如果与之前摆过的皇后在同一列 || 在同一斜线上
        if (record[i] == y || Math.abs(i - x) == Math.abs(record[i] - y)) {
            return false;
        }
    }
    return true;
}


上面这题看着我的注释是非常好理解的,如果还是不理解,可以将4传入,通过调试的方式跟着代码走一遍那就会很清楚了。


第二题


这题相比于上题变化不大,就是不要结果有多少种,而是返回一个 List<List>


其中里面的 List 存了其中一种摆法,例如:


image.png


用:'Q''.' 分别代表了皇后和空位


因为在上一题中我们是有记录 成功摆完所有皇后时皇后位置的,所以我们只要把之前记录代码的地方给去掉 并且把 record 转换为需要的结果那样表达就行了


LinkedList<List<String>> ans = new LinkedList<>();
public List<List<String>> solveNQueens(int n) {
    if (n < 1) return null;
    int[] record = new int[n];
    process(record, 0);
    return ans;
}
public void process(int[] record, int x) {
    if (x == record.length) {
        //对皇后摆放的位置处理为题目要的结果
        handleResult(record);
        return;
    }
    for (int y = 0; y < record.length; y++) {
        if (isVaild(record, x, y)) {
            record[x] = y;
            process(record, x + 1);
        }
    }
}
public boolean isVaild(int[] record, int x, int y) {
    for (int i = 0; i < x; i++) {
        if (record[i] == y || Math.abs(i - x) == Math.abs(record[i] - y)) {
            return false;
        }
    }
    return true;
}
public void handleResult(int[] record) {
    ArrayList<String> list = new ArrayList<>();
    StringBuilder builder = new StringBuilder();
    int row = record.length;  // 行数和列数都为record.length
    int col = record.length;  // 这里分开写只是为了方便理解就用两参数表示
    for (int i = 0; i < col; i++) { //先把棋盘中一行的内容全设为 “.”
        builder.append(".");
    }
    for (int i = 0; i < row; i++) {  // 通过 record 把每行皇后对应位置设置为 "Q"
        StringBuilder tmp = new StringBuilder(builder);
        tmp.replace(record[i], record[i] + 1, "Q");
        list.add(tmp.toString());
    }
    ans.add(list);
}


力扣题目链接:


第一题:leetcode.cn/problems/n-…

第二题:leetcode.cn/problems/n-…

目录
相关文章
|
网络协议 文件存储 Docker
如何搭建HomeAssistant智能家居管理平台并实现公网访问内网管理界面
如何搭建HomeAssistant智能家居管理平台并实现公网访问内网管理界面
|
Linux
RPM 管理软件包的依赖关系
RPM 管理软件包的依赖关系
1281 1
|
移动开发 监控 Serverless
函数计算操作报错合集之在调用api时,遇到404问题该怎么办
在使用函数计算服务(如阿里云函数计算)时,用户可能会遇到多种错误场景。以下是一些常见的操作报错及其可能的原因和解决方法,包括但不限于:1. 函数部署失败、2. 函数执行超时、3. 资源不足错误、4. 权限与访问错误、5. 依赖问题、6. 网络配置错误、7. 触发器配置错误、8. 日志与监控问题。
222 0
|
关系型数据库 MySQL
Mysql客户端下载地址
官网:http://dev.mysql.com/downloads/mysql/   上述千万不要下载免安装版本。 千万记住一定要下载MSI安装版本。
2832 0
|
搜索推荐 Android开发 开发者
Android 自定义组件
Android 自定义组件
182 0
|
网络协议 Unix Shell
Linux CLI 命令行介绍|学习笔记
快速学习 Linux CLI 命令行介绍
Linux CLI 命令行介绍|学习笔记
java202303java学习笔记第三十六天字符输入流的底层原理解析2
java202303java学习笔记第三十六天字符输入流的底层原理解析2
175 0
|
弹性计算 运维 安全
阿里云ecs使用体验
整了台服务器部署项目上线
阿里云ecs使用体验
|
SQL Oracle 关系型数据库