【打卡】【LeetCode学习计划】《数据结构入门-C++》第5天 数组

原文链接:​​​​​​【LeetCode学习计划】《数据结构入门-C++》第5天 数组_Wang_Xin_Ling的博客-CSDN博客

目录

36. 有效的数独LeetCode: 36. 有效的数独

 方法:哈希表

73. 矩阵置零LeetCode: 73. 矩阵置零

方法1:使用标记数组

方法2:使用2个标记变量


36. 有效的数独
LeetCode: 36. 有效的数独

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
1.数字 1-9 在每一行只能出现一次。
2.数字 1-9 在每一列只能出现一次。
3.数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

 方法:哈希表

可以为每一行、每一列和每一个3x3的宫设置一个哈希表,一共是9+9+9=27个哈希表。遍历九宫格的过程中,记录一个元素时需要在它所对应的行、列和宫的哈希表中记录,一个元素一共记录3次。

由于我们一般是按照一行一行地去遍历,所以可以把行哈希表缩减为一个,也就是每一行遍历完后重置哈希表。这样哈希表就变为了1+9+9=19个。

1.

int boxes[3][3][9] = {}   九子宫 一共9元素

2.

const int index = board[i][j] - '0' - 1;

1对应字符‘0’

3.

row[index] == 1 || columns[j][index] == 1 ||  boxes[i / 3][j / 3][index] == 1

就是意味着之前出现了一次了 (因为1对应 字符‘0’)

4.

row[index]++;

columns[j][index]++;

boxes[i / 3][j / 3][index]++;

计数的过程

#include <vector>
using namespace std;
class Solution
{
public:
    bool isValidSudoku(vector<vector<char>> &board)
    {
        int columns[9][9] = {};
        int boxes[3][3][9] = {};

        for (int i = 0; i < 9; i++)
        {
            int row[9] = {};
            for (int j = 0; j < 9; j++)
            {
                if (board[i][j] != '.')
                {
                    const int index = board[i][j] - '0' - 1;
                    if (row[index] == 1 || columns[j][index] == 1 || boxes[i / 3][j / 3][index] == 1)
                        return false;

                    row[index]++;
                    columns[j][index]++;
                    boxes[i / 3][j / 3][index]++;
                }
            }
        }
        return true;
    }
};

 

73. 矩阵置零
LeetCode: 73. 矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地算法。

 

方法1:使用标记数组

假设matrix的行数为m,列数为n,我们可以设置一个m长的rown长的col作为标记数组,用于标记每一行、每一列是否有零出现

我们先完整遍历一次matrix,记录哪里有零;最后根据rowcol数组将matrix对应的行和列全部置零。

#include <vector>
using namespace std;
class Solution
{
public:
    void setZeroes(vector<vector<int>> &matrix)
    {
        const int m = matrix.size(),n = matrix[0].size();
        bool *row = new bool[m]{},*col = new bool[n]{};

        for (int i = 0;i<m;i++)
        {
            for (int j = 0;j < n;j++)
            {
                if (matrix[i][j] == 0)
                {
                    row[i] = true;
                    col[j] = true;
                }
            }
        }
        for (int i = 0;i < m;i++)
        {
            for (int j = 0;j < n;j++)
            {
            if (row[i]  || col[j])
            {
                matrix[i][j] = 0;
            }
            }
        }
    }
};

 

方法2:使用2个标记变量


我们可以用矩阵的第一行和第一列来代替方法1中的标记数组,如果某一行某一列存在0,那么就将原矩阵的第一行和第一列对应的位置置零,这样就能剩下两个额外的数组开销了,并且空间复杂度降为了O ( 1 ) 

不过这样一来,矩阵的第一行第一列原来有没有0就不清楚了,如果第一行或第一列本来就有0的话,最后要把它们单独置零,因此需要两个标记变量分别表示第一行和第一列原先是否含0。

方法2的步骤如下:

标记第一行和第一列中是否含有零。
遍历整个数组,发现0时,更新第一行和第一列对应的位置为零
通过第一行和第一列去更新整个数组

第一行或第一列本身含有零,那么单独为第一行或第一列置零。
 

#include <vector>
using namespace std;
class Solution
{
public:
    void setZeroes(vector<vector<int>> &matrix)
    {
        int m = matrix.size(), n = matrix[0].size();
        bool row0Has0 = false, col0Has0 = false;
        // 设第0行和第0列为标记量
        for (int j = 0; j < n; j++)
        {
            if (matrix[0][j] == 0)
            {
                row0Has0 = true;
                break;
            }
        }
        for (int i = 0; i < m; i++)
        {
            if (matrix[i][0] == 0)
            {
                col0Has0 = true;
                break;
            }
        }

        // 更新标记量
        for (int i = 1; i < m; i++)
        {
            for (int j = 1; j < n; j++)
            {
                if (matrix[i][j] == 0)
                {
                    matrix[0][j] = matrix[i][0] = 0;
                }
            }
        }

        // 使用标记量去更新矩阵
        for (int j = 1; j < n; j++)
        {
            if (matrix[0][j] == 0)
            {
                for (int i = 1; i < m; i++)
                {
                    matrix[i][j] = 0;
                }
            }
        }
        for (int i = 1; i < m; i++)
        {
            if (matrix[i][0] == 0)
            {
                for (int j = 1; j < n; j++)
                {
                    matrix[i][j] = 0;
                }
            }
        }

        if (row0Has0)
        {
            for (int j = 0; j < n; j++)
            {
                matrix[0][j] = 0;
            }
        }
        if (col0Has0)
        {
            for (int i = 0; i < m; i++)
            {
                matrix[i][0] = 0;
            }
        }
    }
};

 

Guess you like

Origin blog.csdn.net/qq_62932195/article/details/121871356