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.

posted @ 2013-12-22 16:04  般若一号  阅读(6262)  评论(0编辑  收藏  举报