回溯Leecode37

写代码没有思路,先将辅助的变量定义好和初始化有助于厘清思路

难点在于一个空格所有数字都尝试失败之后如何回到上一个状态,可以使用List存储需要填写的空格方便回溯使用

还有一个要注意的点是每一格空格填数字的循环中要加上!valid条件,否则得到正确答案后回到上一个空格的遍历循环时还是会继续执行

//每个空格执行进行所有数字的尝试
for (int i = 0; i < 9 && !valid; i++){
    
    
}

完整代码(带测试用例):

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {
    
    
    //是否已经填充
    private boolean[][] rows = new boolean[9][9];
    private boolean[][] columns = new boolean[9][9];
    private boolean[][][] boxes = new boolean[3][3][9];
    private List<int[]> space = new ArrayList<>();
    boolean valid = false;

    //初始化
    public void solveSudoku(char[][] board) {
    
    
        int len = board.length;
        int wid = board[0].length;
        for (int i = 0; i < len; i++) {
    
    
            for (int j = 0; j < wid; j++) {
    
    
                int num = board[i][j] - '0' - 1;
                if('.' == board[i][j]){
    
    
                    space.add(new int[]{
    
    i, j});
                }else{
    
    
                    rows[i][num] = true;
                    columns[j][num] = true;
                    boxes[i / 3][j / 3][num] = true;
                }
            }
        }
        dfs(board,0);
    }

    public void dfs(char[][] board,int start){
    
    
        if(start == space.size()){
    
    
            valid = true;
            return;
        }

        int[] pos = space.get(start);
        int x = pos[0];
        int y = pos[1];

        //这个!valid很重要,当已经完成了正确答案返回到这里的时候就终止循环不要再瞎改了
        // 否则还是会继续把当前的位置改为其他数字
        for (int i = 0; i < 9 && !valid; i++) {
    
    
            //尝试填入数字
            if(!rows[x][i] && !columns[y][i] && !boxes[x / 3][y / 3][i]){
    
    
                rows[x][i] = true;
                columns[y][i] = true;
                boxes[x / 3][y / 3][i] = true;
                board[x][y] = (char) ('0' + i + 1);
                dfs(board,start + 1);
                rows[x][i] = false;
                columns[y][i] = false;
                boxes[x / 3][y / 3][i] = false;
            }
        }
    }

    public void print(){
    
    
        for (boolean[] row : rows) {
    
    
            System.out.println(Arrays.toString(row));
        }
        System.out.println("-----------");

        for (boolean[] column : columns) {
    
    
            System.out.println(Arrays.toString(column));
        }

        System.out.println("------------");
        for (boolean[][] box : boxes) {
    
    
            for (boolean[] booleans : box) {
    
    
                System.out.println(Arrays.toString(booleans));
            }
        }

        System.out.println("--------------");
//        System.out.println(space);
    }

    public static void main(String[] args) {
    
    
        char[][] board =
                {
    
    
                        {
    
    '5','3','.','.','7','.','.','.','.'},
                        {
    
    '6','.','.','1','9','5','.','.','.'},
                        {
    
    '.','9','8','.','.','.','.','6','.'},
                        {
    
    '8','.','.','.','6','.','.','.','3'},
                        {
    
    '4','.','.','8','.','3','.','.','1'},
                        {
    
    '7','.','.','.','2','.','.','.','6'},
                        {
    
    '.','6','.','.','.','.','2','8','.'},
                        {
    
    '.','.','.','4','1','9','.','.','5'},
                        {
    
    '.','.','.','.','8','.','.','7','9'}
                };

        Solution solution = new Solution();
        solution.solveSudoku(board);
//        solution.print();
        for (char[] chars : board) {
    
    
            System.out.println(Arrays.toString(chars));
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41904699/article/details/108745876
37
今日推荐