【力扣每日一题】52.N皇后II

【力扣每日一题】52.N皇后II_第1张图片

八皇后问题是个经典的问题,N皇后问题算是八皇后问题的扩展,都可以通过回溯方法求解。

数据的储存方式:
对于一个nxn的棋盘,最基本的实现方式是使用一个nxn的矩阵M,若矩阵M[i][j]值为1,则表示在点(i,j)处放置一个皇后。但是这个实现方式比较耗内存。
我们知道,一行内最多只能有一个皇后,所以可以使用一个大小为 n 的数组pos,pos[i]即表示在(i,pos[i])处放置一个皇后。这样就能极大的减小内存的开销,同时能更高效的找到已放置皇后的位置。

冲突检测:
两个皇后不能在同一行、列,与斜线上,由于使用单个数组pos存储,不会产生行冲突,对于列冲突,只需判断是否有 pos[i]==pos[j] 。比较复杂的是对角线的冲突,如果对角线会产生冲突,则两个皇后对应两点连成的直线斜率为1或-1,故可用abs(pos[i]-pos[j]) == i-j (i > j)判断。

代码实现:

class Solution {
    // 冲突检测
    bool conflict(vector<int>& pos, int index) {
        for (int i(0); i < index; ++i) {
            if (pos[i] == pos[index] || abs(pos[i]-pos[index]) == index-i) {
                return true;
            }
        }
        return false;
    }
    // 回溯求解
    void backtrack(int& ans, vector<int>& pos, int index, int n) {
        if (index == n) {
            ++ans;
            return;
        }
        for (int i(0); i < n; ++i) {
            pos[index] = i;
            if (!conflict(pos, index)) {
                backtrack(ans, pos, index+1, n);
            }
        }
    }

public:
    int totalNQueens(int n) {
        int ans(0);
        vector<int> pos(n);
        backtrack(ans, pos, 0, n);
        return ans;
    }
};

运行结果:
【力扣每日一题】52.N皇后II_第2张图片

你可能感兴趣的:(力扣,算法)