LeetCode51. N 皇后

 

  N皇后问题也可以转化为树形问题,每一层代表格子的一行,每一个节点都有N种选择。

思路1:以52题的解法为基础,当递归到底时,根据record[]数组的状态信息,还原出皇后的位置。

    判断斜线的方法(参考左神):如果(a,b)满足|a-i|==|b-j|,说明(a,b)和(i,j)处在同一条斜线上。

 

思路2: 

  判断斜线的方法(参考bobo)

   设置两个大小为 2*n-1 的布尔数组,分别为 pie[2*n-1] 和 na[2*n - 1]。 表示n个格子一共有2*n - 1条斜线。

   对角线pie,特点是每一条斜线经过格子的横纵坐标之和相等,因此,pie[i + j] 确定一条斜线。(n为4,pie对角线 i + j 的值分别为0,1,2,3,4,5,6)

   对角线na,特点是每一条斜线经过格子的横纵坐标之差相等,因此,na[i-j+n-1] 确定一条斜线。(n为4,na对角线 i -  j 的值分别为-3,-2,-1,0,1,2,3,为了方便从0开始,加上 4-1=3)

 

代码1(参考左神书,耗时 4ms):  

class Solution {
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        if (n < 1) return res;
        int[] record = new int[n]; // record[i]表示第i行皇后所在的列数
        dfs(0, record, n);
        return res;
    }
    private void dfs(int row, int[] record, int n) {
        if (row == n) {
            res.add(generateBoard(n,record)); // 生成位置信息
            return;
        }
        // 尝试将第row行的皇后摆放在第j列
        for (int j = 0; j < n; j++) {
            if (isValid(record, row, j)) {
                record[row] = j;
                dfs(row + 1, record, n);
            }
        }
    }
    private boolean isValid(int[] record, int row, int j) {
        for (int k = 0; k < row; k++) {
            if (record[k] == j || Math.abs(row - k) == Math.abs(j - record[k])) {
                return false;
            }
        }
        return true;
    }
    // 根据record[]数组的状态信息,还原出皇后的位置。
    // 在52题的基础上,添加此函数即可。
    private List<String> generateBoard(int n, int[] record) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            char[] temp = new char[n];
            Arrays.fill(temp, '.');
            temp[record[i]] = 'Q';
            list.add(new String(temp));
        }
        return list;
    }
}

 

 

代码2(位运算):

M

 

posted @ 2020-12-30 15:44  不学无墅_NKer  阅读(119)  评论(0编辑  收藏  举报