leetcode 52. N皇后 II

leetcode 52. N皇后 II

N 皇后问题, 简单来说就是:同一行,同一列,同一斜线上,只能存在一个皇后。

搜索策略:每行只放一个皇后,搜索第 i 个皇后可以放在第 i 行的第几列(需要枚举每一列), 放好第 i 个皇后, 才去放第 i+1 个皇后, 直到放完所有皇后。

定义:`f[i]` 代表 第 i 个皇后放置在 第 i 行 第 `f[i]` 列上

每行只放一个皇后,因此不必判断行冲突,有以下约束需要满足:

    1. 不能同列,也就是 ` f[i] != f[j] `

    2. 不能同斜线,也就是 ` (i-j) != Math.abs(f[i] - f[j]) `

不能同列很好理解,不能同斜线的不等式是啥意思呢?

leetcode 52. N皇后 II_第1张图片

class Solution {

    // 将 count, queens, f[] 设置为成员变量, 方法 dfs() 中不必再传参了。
    int count; // 表示 n 皇后问题的可行解的个数
    int queens; // 表示 n 个皇后
    int[] f; // f[i] 代表 第 i 个皇后放置在 第 i 行 第 f[i] 列上

    public int totalNQueens(int n) {
        queens = n;
        count = 0;
        f = new int[n+1];

        dfs(1);  // 放置第一个皇后

        return count;

    }



    boolean place(int i) { // 判断 第 i 个 皇后是否有容身之地
        boolean ok = true;
        for(int j = 1; j < i; j++) { // 判断第 i 行的皇后 是否与前 i-1 个皇后的位置冲突了
            if(f[i] == f[j] || i-j == Math.abs(f[i] - f[j])){ // 判断是否存在列冲突 和 斜线冲突
                ok = false;
                break;
            }
        }
        return ok;
    }



    void dfs(int i) { // 搜索 当前 皇后的位置
        if(i > queens) { // 表示已经找到了一个可行解
            count++;
        } else {
            for(int col=1; col<=queens; col++) { // 分别判断每个位置,注意变量 i 不要定义为全局变量,否则递归调用有问题。
                f[i] = col;
                if(place(i))
                    dfs(i+1); // 如果不冲突的话,进行下一个皇后的搜索。
            }
        }
    }
}

参考:《趣学算法》——作者陈小玉老师

你可能感兴趣的:(数据结构和算法,回溯法,Java,N,皇后)