leetcode:Valid Sudoku and Sudoku Solver


Question 1(Valid Sudoku)

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

 

Question 2(Sudoku Solver)

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.

What‘s the difference between above two problems?

The rule of Sudoku: 1. Each row must have the number 1-9 occuring just once.

         2. Each column must have the number 1-9 occuring just once.

         3. The number 1-9 must occur just once in each of sub-boxes of the grid.

 

First, I want to say I don't know how to solve this problem, I see others ideas(http://blog.csdn.net/u011095253/article/details/9158497), but I find a problem. Question 1 (valid Sudoku), you must obey the only above three rules, other things you don't need to care.Question 2 (Sudoku Solver) ,when you try to fill the blank with the suit number, you must make sure they don't violate the above rule.

Second, the Question 2 must use the Depth-First Search, you need a container called Arraylist in Java to memory the blank, then you need to search the grid following the above rule. Below, there are solutions for them from the Internet.

Question 1 (Java )

 

 1         public boolean isValidSudoku(char[][] board){
 2             boolean [][] rows=new boolean[9][9];
 3             boolean [][] cols=new boolean[9][9];
 4             boolean [][] blocks=new boolean[9][9];
 5             for(int i=0;i<9;i++){
 6                 for(int j=0;j<9;j++){
 7                     rows[i][j]=false;
 8                     cols[i][j]=false;
 9                     blocks[i][j]=false;
10                 }
11             }
12             for (int i = 0; i < 9; ++i) {  
13                 for (int j = 0; j < 9; ++j) {
14                     int c = board[i][j] - '1';
15                     if (board[i][j] == '.') continue;  
16                     if (rows[i][c] || cols[j][c] || blocks[i - i % 3 + j / 3][c])  
17                         return false;  
18                     rows[i][c] = cols[j][c] = blocks[i - i % 3 + j / 3][c] = true;  
19                 }  
20             }  
21             return true;  
22         }

 

Question 2(Java)

 

class Solution {
    public void solveSudoku(char[][] board) {
        ArrayList<Integer> array=getArrayList(board);
        DFS(board,array,0);//入口
    }
    
    //記錄每一個空格的位置
    public ArrayList<Integer> getArrayList(char [][]board){
        ArrayList<Integer> array=new ArrayList<Integer>();
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                if(board[i][j]=='.'){
                    array.add(i*9+j);
                }
            }
        }
        return array;
    }
    //深度優先遍歷
    public boolean DFS(char[][]board,ArrayList<Integer> array,int index){
        int len=array.size();
        if(index==len)
            return true;
        int data=array.get(index);
        int row=data/9;
        int column=data%9;
        for(int i=1;i<=9;i++){
            if(isValid(board, row, column, i)){
                board[row][column]=(char) (i+'0');
            if(DFS(board, array, index+1))
                return true;
            board[row][column]='.';
            }
        }
        return false;
    }
    //檢測board是否符合規則
    public boolean isValid(char[][]board,int row,int column,int data){
        for(int i=0;i<9;i++){
            if(board[row][i]-'0'==data)
                return false;
            if(board[i][column]-'0'==data)
                return false;
            int row_s=3*(row/3) + i/3; 
            int column_s=3*(column/3) + i%3;
            if(board[row_s][column_s]-'0'==data)
            return false;
        }
        return true;
    }
}

 

For Question 1: There is a solution similar to Question 2, but the leetcode says can't pass one case, based on this, i find a problem. Below is the code

        public boolean isValidSudoku(char[][] board) {
            for(int i=0;i<9;i++){
                for(int j=0;j<9;j++){
                    if(board[i][j]=='.')
                        continue;
                    if(!isValid(board, i, j, board[i][j]-'0'))
                        return false;
                }
            }
            return true;
        }
        
        //檢測board是否符合規則
        public boolean isValid(char[][]board,int row,int column,int data){
            for(int i=0;i<9;i++){
                if(board[row][i]-'0'==data)
                    return false;
                if(board[i][column]-'0'==data)
                    return false;
                int row_s=3*(row/3) + i/3; 
                int column_s=3*(column/3) + i%3;
                if(board[row_s][column_s]-'0'==data)
                return false;
            }
            return true;
        }

For the case

. 8 7 6 5 4 3  2 1
2 . . . . . . . .
3 . . . . . . . .
4 . . . . . . . .
5 . . . . . . . .
6 . . . . . . . .
7 . . . . . . . .
8 . . . . . . . .
9 . . . . . . . .

the leetcode can pass the Fist solution, and it returns true, means, the above case accord with the Sudoku rule, but we can comfirm it is impossible for us to fill above case. And for the second solution for Question 1, because  it returns false, so it can't be passed, Why? The bug of leetcode? From a friend of foreigner, he have this problem also, another friend from leetcode says, http://oj.leetcode.com/discuss/68/a-case-that-is-not-included, the main idea is you really don't need to care, what you must do is

just to obey the follow the above three rules.Above case accord with the rule. That’s all.If you have some problems, you can contact me.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM