Every day a Leetcode
题目来源:2661. 找出叠涂元素
解法1:哈希
题目很绕,理解题意后就很简单。
由于矩阵 mat 中每一个元素都不同,并且都在数组 arr 中,所以首先我们用一个哈希表 hash 来存储 mat 中每一个元素的位置信息(即行列信息)。然后用一个长度为 m 的数组来表示每一行中已经被涂色的个数,用一个长度为 n 的数组来表示每一列中已经被涂色的个数。其中若出现某一行 i 出现 rowsCount[i]=n 或者某一列 j 出现 colsCount[j]=m,则表示第 i 行或者第 j 列都被涂色。
算法:
- 特判。
- mat 的行数为 m,列数为 n。
- 建立一个哈希表
unordered_map<int, pair<int, int>> hash
,其中key
是mat
中整数值,value
是一个pair<int, int>
,存储的是mat
中key
值的横坐标、纵坐标。 - 遍历
mat
,其中key = mat[i][j]
,pair<int, int> value(i, j)
,插入哈希表hash
中。 - 用一个长度为 m 的数组
rowsCount
来表示每一行中已经被涂色的个数,用一个长度为 n 的数组colsCount
来表示每一列中已经被涂色的个数 - 遍历数组
arr
,设下标为i
,找到arr[i]
在mat
中的横纵坐标:row = hash[arr[i]].first
,col = hash[arr[i]].second
,计数数组对应的行列自增 1,如果发现rowsCount[row] = n
,说明第 row 行的 n 个单元格都被涂上色,返回此时的下标i
;同理,如果发现colsCount[col] = m
,说明第 col 列的 m 个单元格都被涂上色,返回此时的下标i
。
代码:
/*
* @lc app=leetcode.cn id=2661 lang=cpp
*
* [2661] 找出叠涂元素
*/
// @lc code=start
class Solution
{
public:
int firstCompleteIndex(vector<int> &arr, vector<vector<int>> &mat)
{
if (arr.empty() || mat.empty())
return -1;
int m = mat.size(), n = m ? mat[0].size() : 0;
unordered_map<int, pair<int, int>> hash; // <整数,pair<横坐标,纵坐标>>
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
int key = mat[i][j];
pair<int, int> value(i, j);
hash[key] = value;
}
vector<int> rowsCount(m, 0), colsCount(n, 0);
for (int i = 0; i < arr.size(); i++)
{
int row = hash[arr[i]].first, col = hash[arr[i]].second;
rowsCount[row]++;
if (rowsCount[row] == n)
return i;
colsCount[col]++;
if (colsCount[col] == m)
return i;
}
return -1;
}
};
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(m*n),其中 m 和 n 分别是二维数组 mat 的行数和列数。主要为用哈希表存储矩阵 mat 中每一个元素对应行列序号的时间开销。
空间复杂度:O(m*n),其中 m 和 n 分别是二维数组 mat 的行数和列数。主要为用哈希表存储矩阵 mat 中每一个元素对应行列序号的空间开销。