Leetcode --Sudoku Solver

来源:互联网 发布:应用市场软件 编辑:程序博客网 时间:2024/05/17 01:57

问题链接:https://oj.leetcode.com/problems/sudoku-solver/

问题描述:看链接,图多懒得贴。。。

问题API:public void solveSudoku(char[][] board)

问题分析:

这题其实就是和N-queens一样,valid判断和往下递归和traceback。

先给的做法就比较常规,每次都会做判断,往下递归的层级也是有row和column来表示。

    public void solveSudoku(char[][] board) {        solveSudoku(board, 0, 0);    }        public boolean solveSudoku(char[][] board, int col, int row){        if(row >= 9)            return solveSudoku(board, col + 1, 0);        if(col >= 9)            return true;        if(board[col][row] != '.')            return solveSudoku(board, col, row + 1);        for(int k = 1; k <= 9; k++){            if(isValid(board, col, row, k)){//先做validaty的判断,然后再往下递归。                board[col][row] = (char)(k +'0');                if(solveSudoku(board, col, row)){                    return true;                }                board[col][row] = '.';            }        }        return false;    }        public boolean isValid(char[][] board, int col, int row, int num){//这个就和N-queen里面的合理性判断一样        //boolean[] rowMarked = new boolean[10];        //verifying row number;        for(int i = 0; i < board[0].length; i++){            if(board[col][i] == '.')                continue;            if(board[col][i] - '0' == num)                return false;        }        //verifying column number;        boolean[] colMarked = new boolean[10];        for(int i = 0; i < board.length; i++){            if(board[i][row] == '.'){                continue;            }            if(board[i][row] - '0' == num)                return false;        }        //verifying 3x3;        int colstart = (col / 3) * 3;        int rowstart = (row / 3) * 3;        for(int i = 0; i < 3; i++){            for(int j = 0; j < 3; j++){                if(board[colstart + i][rowstart + j] == '.')                    continue;                int idx = board[colstart + i][rowstart + j] - '0';                if(idx == num)                    return false;            }        }        board[col][row] = (char)(num + '0');        return true;    }


另一个做法就相对有效率一些了,用一个0~80的int pos来表示递归的层级和当前的位置,另外用三个boolean[9][9]来实现preprocess了validation,这样子计算效率也提高了很多。分别是rowcheck[9][9],columncheck[9][9],matcheck[9][9],第一维的index表示的是第几个row/column/mat,第二维的index表示1~9的数字是否出现过。当pos到了81,就表示全部东西都已经遍历过了,可以返回true了。

    public void solveSudoku(char[][] board) {        boolean[][] row_check = new boolean[9][9];        boolean[][] col_check = new boolean[9][9];        boolean[][] mat_check = new boolean[9][9];        for(int i = 0; i < 9; i++){            for(int j = 0; j < 9; j++){                if(board[i][j] == '.')                    continue;                row_check[i][board[i][j] - '1'] = true;                col_check[j][board[i][j] - '1'] = true;                mat_check[j / 3 + i / 3 * 3][board[i][j] - '1'] = true;            }        }        helper(0, board, row_check, col_check, mat_check);    }        public boolean helper(int pos, char[][] board, boolean[][] row_check, boolean[][] col_check, boolean[][] mat_check){        if(pos == 81)            return true;        int row = 0, col = 0;        while(pos < 81){            col = pos % 9;            row = pos / 9;            if(board[row][col] == '.')                break;            pos++;        }        if(pos == 81)            return true;        for(char c = '1'; c <= '9'; c++){            if(!row_check[row][c - '1'] && !col_check[col][c - '1'] && !mat_check[col / 3 + row / 3 * 3][c - '1']){                row_check[row][c - '1'] = true;                col_check[col][c - '1'] = true;                mat_check[col / 3 + row / 3 * 3][c - '1'] = true;                board[row][col] = c;                if(helper(pos + 1, board, row_check, col_check, mat_check))                    return true;                board[row][col] = '.';                row_check[row][c - '1'] = false;                col_check[col][c - '1'] = false;                mat_check[col / 3 + row / 3 * 3][c - '1'] = false;                            }        }        return false;    }


0 0
原创粉丝点击