51.N皇后问题

51.N皇后问题_第1张图片

解法

这个题因为之前还是有过印象的,感觉要么是动态规划,要么是回溯法,但这种要输出具体的排列结果的,一般往深度优先回溯想还是没问题的,这个不过太久没写了,回溯的时候想直接for循环搞定,后面发现还是得靠backTrace递归方法,以后回溯先写个递归方法吧,剩下的就是比较巧妙的剪枝过程了,利用正向斜线x+y值相等,反向斜线x-y值相等,可以很方便判断哪些路径是不合适的。

class Solution {

    public List> solveNQueens(int n) {

        // 每行queen放置的位置

        int[] queens = new int[n];

        Arrays.fill(queens, -1);

        // 当前列,左、右斜线出现过queen的集合

        Set columnSet = new HashSet<>();

        Set leftSet = new HashSet<>();

        Set rightSet = new HashSet<>();

        List> res = new ArrayList<>();

        backTrack(0, n, queens, columnSet, leftSet, rightSet, res);

        return res;                  

    }

    private void backTrack(int row, int n, int[] queens, Set columnSet, Set leftSet, Set rightSet, List> res) {

        if (row == n) {

            res.add(genString(queens));

            return;

        }

        for (int j = 0; j < n; j++) {

            if (columnSet.contains(j)) {

                continue;

            }

            int left = row + j;

            if (leftSet.contains(left)) {

                continue;

            }

            int right = row - j;

            if (rightSet.contains(right)) {

                continue;

            }

            queens[row] = j;

            columnSet.add(j);

            leftSet.add(left);

            rightSet.add(right);

            backTrack(row + 1, n, queens, columnSet, leftSet, rightSet, res);

            queens[row] = -1;

            columnSet.remove(j);

            leftSet.remove(left);

            rightSet.remove(right);

        }

    }

    private List genString(int[] queens) {

        int n = queens.length;

        List result = new ArrayList<>();

        for (int i = 0; i < n; i++) {

            char[] a = new char[n];

            Arrays.fill(a, '.');

            a[queens[i]] = 'Q';

            result.add(new String(a));

        }

        return result;

    }

}

你可能感兴趣的:(51.N皇后问题)