首页 > 代码库 > [LeetCode]Valid Sudoku

[LeetCode]Valid Sudoku

检测数独是否合格。

思路:

填充一遍就知道是否合格。

基本暴力搜索的思想。

  1 /***************************************************************************************************
  2 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
  3 The Sudoku board could be partially filled, where empty cells are filled with the character ‘.‘.
  4 Valid Sudoku.png
  5 A partially filled sudoku which is valid.
  6 Note:
  7 A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.
  8 **************************************************************************************************/
  9 #include<stdio.h>
 10 #include<stdbool.h>
 11 
 12 /*检查行*/
 13 bool checkRow(char **line,int i,int length,char c){
 14     for(int j = 0;j < length;j++){
 15         if(line[i][j] == c)return false;
 16     }
 17     return true;
 18 }
 19 
 20 /*检查列*/
 21 bool checkColumn(char **line,int j,int length,char c){
 22     for(int i = 0;i < length;i++){
 23         if(line[i][j] == c)return false;
 24     }
 25     return true;
 26 }
 27 
 28 /*检查九宫格*/
 29 bool checkNCell(char **cell,int i,int j,char c){
 30     for(int m = 0;m < 3;m++){
 31         for(int n = 0;n < 3;n++)
 32             if(cell[i + m][j + n] == c)return false;
 33     }
 34     return true;
 35 }
 36 
 37 /**
 38     board 数独数组
 39     i,j 当前单元格的坐标
 40     boardRowSize 行的上界
 41     boardColSize 列的上界
 42 **/
 43 bool checkSudoku(char **board, int i, int j, int boardRowSize, int boardColSize){
 44     bool result = false;//记录结果
 45     if(board[i][j] == .){//未知数字
 46         for(int k = 1;k < 10;k++){//遍历0->9
 47             if(checkRow(board,i,boardColSize,k + 0) &&
 48                  checkColumn(board,j,boardRowSize,k + 0) &&
 49                  checkNCell(board,(i/3)*3,(j/3)*3,k + 0)){//检测是否能填充该数字
 50                 board[i][j] = k + 0;//填充
 51                 if(i == boardRowSize - 1 && j == boardColSize - 1)return true;//全部填充完毕,数独合格
 52                 else if(j == boardColSize - 1)result = checkSudoku(board,i + 1,0,boardRowSize,boardColSize);//第一行检测完毕,下一行从头开始
 53                 else result = checkSudoku(board,i,j + 1,boardRowSize,boardColSize);//检测同一行的下一格
 54                 if(result)break;//不符合数独
 55                 else board[i][j] = .;
 56             }
 57         }
 58     }else{//已有的数字时跳过
 59         if(i == boardRowSize - 1 && j == boardColSize - 1)return true;//全部检查完毕,数独合格
 60         else if(j == boardColSize - 1)result = checkSudoku(board,i + 1,0,boardRowSize,boardColSize);//一行检查完毕,下一行开始
 61         else result = checkSudoku(board,i,j + 1,boardRowSize,boardColSize);//检测同一行的下一格
 62     }
 63     return result;
 64 }
 65 
 66 /**
 67     *找出正确的解
 68     */
 69 bool isValidSudoku(char** board, int boardRowSize, int boardColSize) {
 70         return checkSudoku(board,0,0,boardRowSize,boardColSize);
 71 }
 72 
 73 void main(){
 74     char **board = (char **)malloc(9*sizeof(char *));
 75     for(int i = 0;i < 9;i++){
 76         board[i] = (char *)malloc(10*sizeof(char));
 77         for(int j = 0;j < 9;j++)
 78             board[i][j] = .;
 79         board[i][9] = \0;
 80     }
 81     board[0][1] = 8;
 82     board[0][2] = 7;
 83     board[0][3] = 6;
 84     board[0][4] = 5;
 85     board[0][5] = 4;
 86     board[0][6] = 3;
 87     board[0][7] = 2;
 88     board[0][8] = 1;
 89     board[1][0] = 2;
 90     board[2][0] = 3;
 91     board[3][0] = 4;
 92     board[4][0] = 5;
 93     board[5][0] = 6;
 94     board[6][0] = 7;
 95     board[7][0] = 8;
 96     board[8][0] = 9;
 97 
 98     printf("result = %d\n",isValidSudoku(board,9,9));
 99     for(int i = 0;i < 9;i++){
100         printf("%s\t\n",board[i]);
101         free(board[i]);
102     }
103     free(board);
104 }

思路2:

题目并没有要求数独必须是能解出来的,所以没有必要这么复杂的去判断。

只需要判断给出的数字中有没有重复的。

/***************************************************************************************************
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 ‘.‘.
Valid Sudoku.png
A partially filled sudoku which is valid.
Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.
**************************************************************************************************/
#include<stdio.h>
#include<stdbool.h>

/*检查出现的数字中是否有重复的*/
bool checkRow(char **line,int i,int length){
    int a[10] = {0};
    for(int j = 0;j < length;j++){
        if(line[i][j] != .)a[line[i][j] - 0]++;
    }

    for(int j = 0;j < 10;j++){
        if(a[j] > 1)return false;
    }
    return true;
}

/*检查出现的数字中是否有重复的*/
bool checkColumn(char **line,int j,int length){
    int a[10] = {0};
    for(int i = 0;i < length;i++){
        if(line[i][j] != .)a[line[i][j] - 0]++;
    }

    for(int i = 0;i < 10;i++){
        if(a[i] > 1)return false;
    }
    return true;
}

/*检查出现的数字中是否有重复的*/
bool checkNCell(char **cell,int i,int j){
    int a[10] = {0};
    for(int m = 0;m < 3;m++){
        for(int n = 0;n < 3;n++){
            if(cell[i + m][j + n] != .)a[cell[i + m][j + n] - 0]++;
        }
    }

    for(int k = 0;k < 10;k++){
        if(a[k] > 1)return false;
    }
    return true;
}

bool isValidSudoku(char** board, int boardRowSize, int boardColSize) {
        int i,j;
        for(i = 0;i < boardRowSize;i++){//检测行
            if(!checkRow(board,i,boardColSize))return false;
        }
        for(i = 0;i < boardColSize;i++){//检测列
            if(!checkColumn(board,i,boardRowSize))return false;
        }

        for(i = 0,j = 0;i < boardRowSize && j < boardColSize;j += 3){//检测列
            if(!checkNCell(board,i,j))return false;
            if(j == boardColSize - 3){
                i += 3;
                j = -3;
            }
        }
        return true;
}

void main(){
    char **board = (char **)malloc(9*sizeof(char *));
    for(int i = 0;i < 9;i++){
        board[i] = (char *)malloc(10*sizeof(char));
        for(int j = 0;j < 9;j++)
            board[i][j] = .;
        board[i][9] = \0;
    }
    board[0][2] = 1;
    board[0][6] = 3;
    board[1][2] = 4;
    board[1][6] = 1;
    board[3][4] = 8;
    board[4][1] = 1;
    board[4][4] = 2;
    board[5][6] = 6;
    board[5][7] = 3;
    board[6][0] = 7;
    board[7][0] = 5;
    board[7][1] = 8;
    board[7][6] = 4;
    board[8][1] = 5;
    board[8][4] = 4;
    board[8][8] = 8;

    printf("result = %d\n",isValidSudoku(board,9,9));
    for(int i = 0;i < 9;i++){
        printf("%s\t\n",board[i]);
        free(board[i]);
    }
    free(board);
}

 

[LeetCode]Valid Sudoku