【leetcode】36. 有效的数独

题目

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

题目链接:https://leetcode-cn.com/problems/valid-sudoku/

上图是一个部分填充的有效的数独。

数独部分空格内已填入了数字,空白格用 '.' 表示。

示例 1:

输入:
[
  ["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"]
]
输出: true

说明:

一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
给定数独序列只包含数字 1-9 和字符 '.' 。
给定数独永远是 9x9 形式的。

分析:这道题采用C语言的uthash求解,当然有别的更简单的解法,我这里求解只是为了练习uthash,与上一道题【136. 只出现一次的数字】不同的是,这里用的是数组指针,并且所有封装函数的参数均增加了hash指针,用于对不同的hash表操作,重新封装后的uthash如下:

struct my_struct {
    int id; /* key */
    char name[20];
    UT_hash_handle hh; /* makes this structure hashable */
};

struct my_struct *g_hash_row[9] = {NULL};
struct my_struct *g_hash_col[9] = {NULL};
struct my_struct *g_hash_box[9] = {NULL};

void hash_add_ikey(struct my_struct **hash, int ikey_id, char *name)
{
    struct my_struct *s;

    HASH_FIND_INT(*hash, &ikey_id, s); /* id already in the hash? */
    if (s == NULL) {
        s = (struct my_struct *)malloc(sizeof *s);
        s->id = ikey_id;
        HASH_ADD_INT(*hash, id, s); /* id: name of key field */
    }
    // strcpy_s(s->name, 10 * sizeof(char), name); // 自行判断是否使用安全函数,这里不要sizeof(s->name)
    strcpy(s->name, name);
}

struct my_struct *hash_find_ikey(struct my_struct **hash, int ikey_id)
{
    struct my_struct *s;

    HASH_FIND_INT(*hash, &ikey_id, s); /* s: output pointer */
    return s;
}

void hash_delete_ikey(struct my_struct **hash, struct my_struct *ikey)
{
    struct my_struct *s = NULL;

    HASH_FIND_INT(*hash, &ikey, s);
    if (s == NULL) {
        HASH_DEL(*hash, ikey); /* ikey: pointer to delete */
        free(ikey);
    }
}

void hash_delete_all(struct my_struct **hash)
{
    struct my_struct *current_ikey, *tmp;

    HASH_ITER(hh, *hash, current_ikey, tmp)
    {
        HASH_DEL(*hash, current_ikey); /* delete it (g_hash advances to next) */
        free(current_ikey);             /* free it */
    }
}

void hash_print(struct my_struct **hash)
{
    struct my_struct *s;

    for (s = *hash; s != NULL; s = (struct my_struct *)(s->hh.next)) {
        printf("ikey id %d: name %s\n", s->id, s->name);
    }
}

int name_sort(struct my_struct *a, struct my_struct *b)
{
    return strcmp(a->name, b->name);
}

int id_sort(struct my_struct *a, struct my_struct *b)
{
    return (a->id - b->id);
}

void hash_sort_by_name(struct my_struct **hash)
{
    HASH_SORT(*hash, name_sort);
}

void hash_sort_by_id(struct my_struct **hash)
{
    HASH_SORT(*hash, id_sort);
}

unsigned int hash_get_count(struct my_struct **hash)
{
    return HASH_COUNT(*hash);
}

主函数代码如下,注意每一个return分支都需要clear hash,以免全部变量值对下一个用例产生影响。

void hash_clear()
{
    for (int i = 0; i < 9; i++) {
        hash_delete_all(&g_hash_row[i]);
        hash_delete_all(&g_hash_col[i]);
        hash_delete_all(&g_hash_box[i]);
    }
}

bool isValidSudoku(char** board, int boardSize, int* boardColSize){
    if (boardSize <= 0 || boardColSize == NULL || *boardColSize <= 0 || board == NULL) {
        return false;
    }

    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (board[i][j] == '.') {
                continue;
            }
            if (hash_find_ikey(&g_hash_row[i], board[i][j]) == NULL) {
                hash_add_ikey(&g_hash_row[i], board[i][j], "g_hash_row");
            } else {
                hash_clear();
                return false;
            }
            if (hash_find_ikey(&g_hash_col[j], board[i][j]) == NULL) {
                hash_add_ikey(&g_hash_col[j], board[i][j], "g_hash_col");
            } else {
                hash_clear();
                return false;
            }
            if (hash_find_ikey(&g_hash_box[i/3*3 + j/3], board[i][j]) == NULL) {
                hash_add_ikey(&g_hash_box[i/3*3 + j/3], board[i][j], "g_hash_box");
            } else {
                hash_clear();
                return false;
            }
        }
    }

    hash_clear();
    return true;
}

 

你可能感兴趣的:(leetcode)