Day 5 有效数独和旋转矩阵

今天还是继续向后完成两道题,分别是判断一个数独是否有效,还有旋转一个矩阵。

有效数独

这题是第36题,题目意思是说给定一个初始的数独,判断该初始数独是否有效,也就是行,列以及每一个3×3的小方格中是否有重复的数字,如果没有重复的数字就是有效数独。

想法就是分别进行行判断,列判断,以及3×3格子中的判断。定义一个用来记录每个数字在行和列中出现次数的数组,如果在行判断或列判断中,有数字的记录出现2次,那就不是一个有效的数独。在3×3格子中进行判断的时候,还需要定义一个用来计数的变量,用来指示是否判断了3列,如果已经判断了3列就将其清零。算法中减去48是因为该数独是用char类型进行定义,而flag数组是int型,char类型的0转换成十进制是48.还有flag数组在每次初始化是要循环到数组下标为9的位置,因为对于该数组我们使用的是下标1~9这9位,因此在分配内存的时候需要分配10个int类型空间。

bool isValidSudoku(char** board, int boardSize, int* boardColSize) {
    int i = 0, j = 0, k = 0, count = 0;
    int* flag = (int*)malloc(sizeof(int) * 10);
    for (i = 0; i < 9; i++) {
        for (k = 0; k <= 9; k++) {
            flag[k] = 0;
        }
        for (j = 0; j < 9; j++) {
            if (board[i][j] != '.') {
                flag[board[i][j] - 48] += 1;
                if (flag[board[i][j] - 48] == 2) {
                    return false;
                }
            }
        }
    }
    for (i = 0; i < 9; i++) {
        for (k = 0; k <= 9; k++) {
            flag[k] = 0;
        }
        for (j = 0; j < 9; j++) {
            if (board[j][i] != '.') {
                flag[board[j][i] - 48] += 1;
                if (flag[board[j][i] - 48] == 2) {
                    return false;
                }
            }
        }
    }
    for (int i = 0; i < 7; i += 3) {//3*3判断
        for (int k = 0; k <= 9; k++)flag[k] = 0;
        for (int j = 0; j < 9; j++) {
            if (count % 3 == 0)//每判断一个3*3就清零
                for (int k = 0; k <= 9; k++)flag[k] = 0;
            if (board[i][j] != '.') {
                flag[board[i][j] - 48]++;
                if (flag[board[i][j] - 48] == 2)return false;
            }
            if (board[i + 1][j] != '.') {
                flag[board[i + 1][j] - 48]++;
                if (flag[board[i + 1][j] - 48] == 2)return false;
            }
            if (board[i + 2][j] != '.') {
                flag[board[i + 2][j] - 48]++;
                if (flag[board[i + 2][j] - 48] == 2)return false;
            }
            count++;
        }
    }
    return true;
}

旋转矩阵

对于旋转矩阵来说就更好理解了,将一个矩阵进行旋转,原先第一行的元素变成了倒数第一列的元素,第二行的元素变成了倒数第二列的元素,以此类推,因此只需要再定义一个空的矩阵,将相应的元素填入,最后再将新定义的矩阵中的数再填入原先的数组即可。

void rotate(int** matrix, int matrixSize, int* matrixColSize) {
    int matrix_new[matrixSize][matrixSize];
    for (int i = 0; i < matrixSize; i++) {
        for (int j = 0; j < matrixSize; j++) {
            matrix_new[i][j] = matrix[i][j];
        }
    }
    for (int i = 0; i < matrixSize; ++i) {
        for (int j = 0; j < matrixSize; ++j) {
            matrix[j][matrixSize - i - 1] = matrix_new[i][j];
        }
    }
}

力扣官方题解

题解中还有一种原地的旋转,还没有仔细地读下来,所以就明天弄懂了再写吧,这样初级算法中的数组部分就结束了,明天复习一下就继续之后的字符串算法的学习了。

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值