检查是否每一行每一列都包含完整整数
题目及要求
对一个大小为 n x n 的矩阵而言,如果其每一行和每一列都包含从 1 到 n 的 全部 整数(含 1 和 n),则认为该矩阵是一个 有效 矩阵。
给你一个大小为 n x n 的整数矩阵 matrix ,请你判断矩阵是否为一个有效矩阵:如果是,返回 true ;否则,返回 false 。
示例 1:
输入:matrix = [[1,2,3],[3,1,2],[2,3,1]]
输出:true
解释:在此例中,n = 3 ,每一行和每一列都包含数字 1、2、3 。
因此,返回 true 。
示例 2:
输入:matrix = [[1,1,1],[1,2,3],[1,2,3]]
输出:false
解释:在此例中,n = 3 ,但第一行和第一列不包含数字 2 和 3 。
因此,返回 false 。
提示:
n == matrix.length == matrix[i].length
1 <= n <= 100
1 <= matrix[i][j] <= n
暴力算法
解题思路:暴力不用思路,直接判断每一行每一列,全部满足就返回true,否则返回false
bool checkValid(vector<vector<int>>& m) { // 定义函数,参数为二维矩阵m
bool flag = true; // 初始化标志位为true
int n = m.size(); // 获取矩阵大小,n为矩阵的边长
bool st[n+1]; // 定义数组st,用于存储数字是否出现过
for (int i=0;i<n;i++) // 对于每一行进行遍历
{
memset(st,0,sizeof st); // 将st中的所有元素初始化为false
for (int j=0;j<n;j++) // 对于该行中的每个元素进行遍历
{
st[m[i][j]] = true; // 将该元素在st中对应的位置改为true
}
for (int j=1;j<=n;j++) // 遍历1到n,检查每个数字是否都出现过
{
if (!st[j]) // 如果有数字没有出现过,则标志位置为false
{
flag = false;
break;
}
}
memset(st,0,sizeof st); // 将st中的所有元素初始化为false
for (int j=0;j<n;j++) // 对于该列中的每个元素进行遍历
{
st[m[j][i]] = true; // 将该元素在st中对应的位置改为true
}
for (int j=1;j<=n;j++) // 遍历1到n,检查每个数字是否都出现过
{
if (!st[j]) // 如果有数字没有出现过,则标志位置为false
{
flag = false;
break;
}
}
if (!flag) break; // 如果已经发现有数字没有出现,则退出循环
}
return flag; // 返回标志位
}
哈希集合(std::unordered_set)来快速判断
解题思路:创建哈希集合,运用哈希集合中的count来判断当前列和行内的整数是否重复,若重复则不符合题目(都包含从 1 到 n 的 全部 整数)返回false,全部查找完之后没有重复的则返回一个true
class Solution {
public:
bool checkValid(std::vector<std::vector<int>>& matrix) {
int n = matrix.size();
std::unordered_set<int> rowSet; // 存储每一行出现的元素
std::unordered_set<int> colSet; // 存储每一列出现的元素
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (rowSet.count(matrix[i][j]) > 0 || colSet.count(matrix[j][i]) > 0) {
return false; // 如果当前元素在行或列中已经出现过,返回false
}
rowSet.insert(matrix[i][j]); // 将当前元素加入行集合中
colSet.insert(matrix[j][i]); // 将当前元素加入列集合中
}
rowSet.clear(); // 清空行集合,准备记录下一行的元素
colSet.clear(); // 清空列集合,准备记录下一列的元素
}
return true; // 所有元素都没有重复,返回true
}
};