LeetCode--51:N皇后(java)

原题链接
如果在[ i, j ] (第 i 行 第 j 列)位置上放置了皇后,则下述位置不能再放皇后:

  • 整个 i 行所有位置
  • 整个 j 列所有位置
  • 如果位置(a, b)满足 | a - i | = | b - j |(两个位置的横坐标之差等于纵坐标之差),则(a, b)处不能放皇后,因为此时位置(a, b)处于(i, j)位置上的皇后的斜向攻击范围

解题思路:
       按行(row)对棋盘进行递归,对于每一行,遍历该行的所有列(col),寻找可以放置皇后的位置,我们用 queen 数组记录可以放置皇后的位置,queen[row] = col 表示第 row 行的皇后位于第 col 列。
       如果某一行的所有列都不能放置皇后,则不再递归下一行。只要存在一个可以放置皇后的位置,就继续递归下一行。
       如果递归到最后 row = n,说明整个棋盘遍历完了,整张棋盘上的所有皇后位置都记录在 queen 数组中了,所以遍历该数组即为一种可行的方案。

class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> res = new ArrayList<>();
        if(n < 1) return res;
        int[] queen = new int[n];
        process(n, 0, queen, res);
        return res; 
    }
    public void process(int n, int row, int[] queen, List<List<String>> res){
        if(row == n){//说明整张棋盘都遍历完了,并且每一行都有皇后
            ArrayList<String> tmp = new ArrayList<>();
            for(int i = 0;i < n;i++){//遍历queen数组,得到一种可行解
                StringBuilder s = new StringBuilder();
                for(int j = 0;j < n;j++){
                    if(j == queen[i]){//如果遍历到了 i 行皇后所在的列
                        s.append('Q');//就添加Q
                    }else{
                        s.append('.');
                    }
                }
                tmp.add(s.toString());
            }
            res.add(tmp);
        }
        for(int col = 0;col < n;col++){//遍历该行的每一列,寻找有效的位置
            if(isValid(queen, row, col)){
                queen[row] = col;//(row,col)可以放皇后,则更新queen数组
                process(n, row + 1, queen, res);//并且递归下一行
            }
        }
    }
    public boolean isValid(int[] queen, int row, int col){
        for(int k = 0;k < row;k++){//遍历 row 之前的每一行
        //如果某一行的皇后位于第 col 列 || (row,col)位于某一行皇后的斜向攻击范围上
            if(col == queen[k] || Math.abs(k - row) == Math.abs(queen[k] - col)){
                return false;
            }
        }
        return true;
    }
}

LeetCode--51:N皇后(java)_第1张图片

你可能感兴趣的:(LeetCode)