• 【算法 C】Leetcode 36. Valid Sudoku 有效的数独


    其实算法并没有太难,无论是3次遍历还是1次遍历,都不会超时,我在做的时候,如何使用测试数据反而困扰了我很久。

    读取测试数据

    将测试数据放在文件中读取,这里将文件指针改为stdin应该也是一样的效果。

    #include <stdio.h>
    #include <stdbool.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        int boardSize = 9;
        int boardColSize = 9;
        char** board = (char **) malloc(sizeof(char *) * boardSize);
    
        // 打开文件
        FILE *fp = fopen("sudoku1.txt", "r");
        if (fp == NULL)
        {
            fprintf(stderr, "读取文件出错");
            exit(-1);
        }
    
        // 输出文件内容
        printf("文件内容为:
    ");
        int ch;
        while ((ch = fgetc(fp)) != EOF)
        {
            putchar(ch);
        }
        printf("
    ");
    
        // 读取数组
        rewind(fp);
        for (int i = 0; i < boardSize; i++)
        {
            board[i] = (char *) malloc(sizeof(char) * boardSize);  // 每行分配内存
            for (int j = 0; j < boardColSize; j++)
            {
                while ((ch = fgetc(fp)) != EOF && ch != '"');
                board[i][j] = fgetc(fp);
                fgetc(fp);
            }
        }
        fclose(fp);
    
        // 输出查看数组
        printf("读取到数组为: 
    ");
        for (int i = 0; i < boardSize; i++)
        {
            for (int j = 0; j < boardColSize; j++)
            {
                printf("%c ", board[i][j]);
            }
            printf("
    ");
        }
    
        // solve
        bool validate = isValidSudoku(board, boardSize, &boardColSize);
        puts(validate ? "true": "false");
        // 释放内存
        for (int i = 0; i < boardSize; i++)
        {
            free(board[i]);
        }
        free((void *) board);
        return 0;
    }
    

    3次遍历

    #include <stdio.h>
    #include <stdbool.h>
    #include <stdlib.h>
    #include <string.h>
    bool isValidSudoku(char** board, int boardSize, int* boardColSize)
    {
        int nums[10] = {0};
        int tmp;
        // 检查行
        for(int i = 0; i < boardSize; i++)
        {
            memset(nums, 0, sizeof(int) * 10);
            for(int j = 0; j < *boardColSize; j++)
            {
                tmp = board[i][j];
                if (tmp <= '9' && tmp > '0')
                {
                    tmp = board[i][j] - '0';
                    nums[tmp] += 1;
                    if (nums[tmp] > 1)
                    {
    //					printf("false原因(行): [%d, %d]", i, j);
                        return false;
                    }
                }
    
            }
        }
        // 检查列
        for(int j = 0; j < *boardColSize; j++)
        {
           memset(nums, 0, sizeof(int) * 10);
            for(int i = 0; i < boardSize; i++)
            {
                tmp = board[i][j];
                if (tmp <= '9' && tmp > '0')
                {
                    tmp = board[i][j] - '0';
                    nums[tmp] += 1;
                    if (nums[tmp] > 1)
                    {
    //                	printf("false原因(列): [%d, %d]", i, j);
                        return false;
                    }
                }
    
            }
        }
        // 检查九宫格
        for (int i = 0; i < boardSize / 3; i++)
        {
            for (int j = 0; j < *boardColSize / 3; j++)
            {
                memset(nums, 0, sizeof(int) * 10);
                for (int k = 0; k < 3; k++)
                {
                    for (int l = 0; l < 3; l++)
                    {
                        tmp = board[i * 3 + k][j * 3 + l];
                        if (tmp <= '9' && tmp > '0')
                        {
                            tmp = tmp - '0';
                            nums[tmp] += 1;
                            if (nums[tmp] > 1)
                            {
    //                        	printf("false原因9: [%d, %d]", i * 3 + k, j * 3 + l);
                                return false;
                            }
                        }
                    }
                }
            }
        }
        return true;
    }
    
    int main()
    {
        int boardSize = 9;
        int boardColSize = 9;
        char** board = (char **) malloc(sizeof(char *) * boardSize);
    
        // 打开文件
        FILE *fp = fopen("sudoku1.txt", "r");
        if (fp == NULL)
        {
            fprintf(stderr, "读取文件出错");
            exit(-1);
        }
    
        // 输出文件内容
        printf("文件内容为:
    ");
        int ch;
        while ((ch = fgetc(fp)) != EOF)
        {
            putchar(ch);
        }
        printf("
    ");
    
        // 读取数组
        rewind(fp);
        for (int i = 0; i < boardSize; i++)
        {
            board[i] = (char *) malloc(sizeof(char) * boardSize);  // 每行分配内存
            for (int j = 0; j < boardColSize; j++)
            {
                while ((ch = fgetc(fp)) != EOF && ch != '"');
                board[i][j] = fgetc(fp);
                fgetc(fp);
            }
        }
        fclose(fp);
    
        // 输出查看数组
        printf("读取到数组为: 
    ");
        for (int i = 0; i < boardSize; i++)
        {
            for (int j = 0; j < boardColSize; j++)
            {
                printf("%c ", board[i][j]);
            }
            printf("
    ");
        }
    
        // solve
        bool validate = isValidSudoku(board, boardSize, &boardColSize);
    	puts(validate ? "true": "false");
        // 释放内存
        for (int i = 0; i < boardSize; i++)
        {
            free(board[i]);
        }
        free((void *) board);
        return 0;
    }
    
    

    一次遍历

    #include <stdio.h>
    #include <stdbool.h>
    #include <stdlib.h>
    #include <string.h>
    bool isValidSudoku(char** board, int boardSize, int* boardColSize)
    {
    
        /* 一次遍历 */
        int row[9][9] = {0};
        int col[9][9] = {0};
        int box[9][9] = {0};
        int boxIndex;
        int tmp;
        for (int i = 0; i < 9; i++)
        {
            for (int j = 0; j < 9; j++)
            {
                tmp = board[i][j];
                if (tmp >='1' && tmp <= '9')
                {
                    tmp -= '1';
                    boxIndex = (i / 3) * 3 + j / 3;
                    row[i][tmp] += 1;
                    col[j][tmp] += 1;
                    box[boxIndex][tmp] += 1;
    
                    if (row[i][tmp] > 1 || col[j][tmp] > 1 || box[boxIndex][tmp] > 1)
                    {
                        return false;
                    }
                }
    
            }
        }
    
        return true;
    }
    
    int main()
    {
        int boardSize = 9;
        int boardColSize = 9;
        char** board = (char **) malloc(sizeof(char *) * boardSize);
    
        // 打开文件
        FILE *fp = fopen("sudoku1.txt", "r");
        if (fp == NULL)
        {
            fprintf(stderr, "读取文件出错");
            exit(-1);
        }
    
        // 输出文件内容
        printf("文件内容为:
    ");
        int ch;
        while ((ch = fgetc(fp)) != EOF)
        {
            putchar(ch);
        }
        printf("
    ");
    
        // 读取数组
        rewind(fp);
        for (int i = 0; i < boardSize; i++)
        {
            board[i] = (char *) malloc(sizeof(char) * boardSize);  // 每行分配内存
            for (int j = 0; j < boardColSize; j++)
            {
                while ((ch = fgetc(fp)) != EOF && ch != '"');
                board[i][j] = fgetc(fp);
                fgetc(fp);
            }
        }
        fclose(fp);
    
        // 输出查看数组
        printf("读取到数组为: 
    ");
        for (int i = 0; i < boardSize; i++)
        {
            for (int j = 0; j < boardColSize; j++)
            {
                printf("%c ", board[i][j]);
            }
            printf("
    ");
        }
    
        // solve
        bool validate = isValidSudoku(board, boardSize, &boardColSize);
        puts(validate ? "true": "false");
        // 释放内存
        for (int i = 0; i < boardSize; i++)
        {
            free(board[i]);
        }
        free((void *) board);
        return 0;
    }
    
    
  • 相关阅读:
    ElasticSearch原理
    redis master配置了密码进行主从同步
    redis sentinel 高可用(HA)方案部署,及python应用示例
    Linux Redis集群搭建与集群客户端实现
    字符串倒序
    单链表反转
    【python】面试常考数据结构算法
    面试中的排序算法总结
    Memcached 真的过时了吗?
    Activity生命周期
  • 原文地址:https://www.cnblogs.com/XD00/p/13205482.html
Copyright © 2020-2023  润新知