带你轻松拿捏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-…

目录
相关文章
|
4月前
数字游戏2(数位dp)
数字游戏2(数位dp)
31 0
|
4月前
|
算法 测试技术 C#
【广度优先搜索】【分类讨论】900. 最佳运动员的比拼回合
【广度优先搜索】【分类讨论】900. 最佳运动员的比拼回合
|
3月前
1037 在霍格沃茨找零钱
1037 在霍格沃茨找零钱
|
4月前
代码随想录Day29 贪心04 LeetCode T860 柠檬水找零 T406 根据身高重建队列 T452 用最少得箭引爆气球
代码随想录Day29 贪心04 LeetCode T860 柠檬水找零 T406 根据身高重建队列 T452 用最少得箭引爆气球
34 0
|
算法
【过河卒】回溯算法保姆式解题
【过河卒】回溯算法保姆式解题
71 0
洛谷P1135 奇怪的电梯——广搜
洛谷P1135 奇怪的电梯——广搜
90 0
|
存储 移动开发 算法
C++/PTA 关于深度优先搜索和逆序对的题应该不会很难吧这件事
背景知识 深度优先搜索与 DFS 序 深度优先搜索算法(DFS)是一种用于遍历或搜索树或图的算法。以下伪代码描述了在树 T 上进行深度优先搜索的过程
103 0
|
算法 JavaScript 前端开发
日拱算法:解两道“杨辉三角”题
什么是“杨辉三角”,想必大家并不陌生~~ 在「杨辉三角」中,每个数是它左上方和右上方的数的和。
|
机器学习/深度学习 算法
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
|
算法
贪心算法——小船过河
贪心算法——小船过河
360 0
贪心算法——小船过河