Leetcode51-52 N皇后、N皇后II

Leetcode51:N皇后

题目:N皇后问题是把N个皇后放在一个N×N棋盘上,使皇后之间不会互相攻击(任意两个皇后都不能处于同一行、同一列或同一斜线上)。给出一个整数n,返回n皇后问题的所有摆放方案。

        ​

分析:对于N皇后问题,首先注意到两个细节,第一,一行只可能有一个皇后且一列也只可能有一个皇后;第二,对于所有的主对角线有行号 + 列号 = 常数,对于所有的次对角线(x = y)有行号 - 列号 = 常数。因为每行每列主副对角线不能有多个皇后,所以我们可以先考虑皇后放在第一行中的每个位置,定义列,主副对角线数组来记录该位置的三个方向是否已经存在皇后,如果不存在,就进行放置,并且对这个位置的三个方向进行标记,递归求解下一行的皇后位置,然后再进行回溯求解其它的解。

    //定义列、主对角线、副对角线
    private boolean[] col;
    private boolean[] dia1;
    private boolean[] dia2;
    private List<List<String>> result = new ArrayList<>();

    public List<List<String>> solveNQueens(int n) {
        List<String> list = new ArrayList<>();
        col = new boolean[n];
        dia1= new boolean[2*n-1];
        dia2 = new boolean[2*n-1];
        putQueen(n,list,0);
        return result;
    }

    private void putQueen(int n, List<String> list, int row) {
        if(row == n){
            result.add(new ArrayList<>(list));
            return;
        }
        char[] ch = new char[n];
        Arrays.fill(ch, '.');
        // 遍历当前 row 行的所有位置
        for(int i = 0;i < n;i++){
            if(!col[i] && !dia1[row-i+n-1] && !dia2[row+i]){
                //试探
                ch[i] = 'Q';list.add(String.valueOf(ch));
                col[i] = true;dia1[row-i+n-1] = true;dia2[row+i] = true;
                putQueen(n,list,row + 1);//试着寻找下一行
                //回溯
                list.remove(list.size() - 1);ch[i] = '.';
                col[i] = false;dia1[row-i+n-1] = false;dia2[row+i] = false;
            }
        }
    }

Leetcode52:N皇后II

题目:继续思考“n-queens”问题。这次我们不是输出皇后的排列情况,而是输出n皇后问题一共有多少种解法

分析:思路跟上题一样,只是我们不需要记录每次结果皇后的排列情况,而只是添加计数器来求解解法个数。

    //定义列、主对角线、副对角线
    private boolean[] col;
    private boolean[] dia1;
    private boolean[] dia2;
    private int count;
    public int totalNQueens(int n) {
        col = new boolean[n];
        dia1= new boolean[2*n-1];
        dia2 = new boolean[2*n-1];
        putQueen(n,0);
        return count;
    }

    private void putQueen(int n,int row) {
        if(row == n){
            count++;
            return;
        }
        // 遍历当前 row 行的所有位置
        for(int i = 0;i < n;i++){
            if(!col[i] && !dia1[row-i+n-1] && !dia2[row+i]){
                //试探
                col[i] = true;dia1[row-i+n-1] = true;dia2[row+i] = true;
                putQueen(n,row + 1);//试着寻找下一行
                //回溯
                col[i] = false;dia1[row-i+n-1] = false;dia2[row+i] = false;
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/Nibaby9/article/details/106006299
今日推荐