代码随想录_回溯系列

leetcode51 八皇后问题

皇后会对同一行、同一列、同一左斜对角线、同一右斜对角线的皇后发起攻击。
使用point数组来记录每个皇后放置的位置,使用canUse来确定该行哪个位置能放置皇后。
现在有两个皇后,其坐标分别为(x1,y1),(x2,y2)
同一左斜对角线的数学规律:x1-y1 = x2-y2
同一右斜对角线的数学规律:x1+y1 = x2+y2

class Solution {
    private List<List<String>> ans = new ArrayList();
   
    private void backtracking(int depth, int n, int point[]) {
        if(depth == n) {
            List<String> path = new ArrayList();
            for(int i = 0; i < n; i++) {
                char[] initialStr = new char[n];
                Arrays.fill(initialStr, '.');
                initialStr[point[i]] = 'Q';
                path.add(String.valueOf(initialStr));
            }
            ans.add(path);
            return;
        }
        boolean[] canUse = new boolean[n];
        Arrays.fill(canUse, true);
        for(int i = 0; i < depth; i++) {
            // col
            canUse[point[i]] = false;
            // right diagonal
            int diagonal = point[i] + i - depth;
            if(0 <= diagonal && diagonal < n) canUse[diagonal] = false;
            // left diagonal
            diagonal =  depth - i + point[i];
            if(0 <= diagonal && diagonal < n) canUse[diagonal] = false;
        }
        for(int i = 0; i < n; i++) {
            if(canUse[i] == true) {
                point[depth] = i;
                canUse[i] = false;
                backtracking(depth+1, n, point);
                canUse[i] = true;
                point[depth] = -1;
            }
        }
    }

    public List<List<String>> solveNQueens(int n) {
        // 第i行上放置的数字
        int[] point = new int[n];
        Arrays.fill(point, -1);
        backtracking(0, n, point);
        return ans;
    }
}

leetcode37 解数独

class Solution {
    private boolean isValid(int m, int n, char k, char[][] board) {
        for(int j = 0; j < 9; j++) {
            if(board[m][j] == k) return false;
        }
        for(int i = 0; i < 9; i++) {
            if(board[i][n] == k) return false;
        }
        int startR = (m / 3) * 3;
        int startC = (n / 3) * 3;
        for(int i = startR; i < startR + 3; i++) {
            for(int j = startC; j < startC + 3; j++) {
                if(board[i][j] == k) return false;
            }
        }
        return true;
    }
    
    private boolean backtracking(char[][] board) {
        for(int i = 0; i < 9; i++) {
            for(int j = 0; j < 9; j++) {
                if(board[i][j] != '.') continue;
                for(char k = '1'; k <= '9'; k++) {
                    if(isValid(i,j,k,board) == true) {
                        board[i][j] = k;
                        if(backtracking(board)) return true;
                        board[i][j] = '.';
                    }
                }
                return false;
            }
        }
        return true;
    }
    public void solveSudoku(char[][] board) {
        backtracking(board);
        return;
    }
}
posted @ 2022-05-12 15:14  明卿册  阅读(36)  评论(0编辑  收藏  举报