题目(难度中等)
给你一个下标从 0 开始的整数数组 arr 和一个 m x n 的整数 矩阵 mat 。arr 和mat 都包含范围 [1,m * n] 内的 所有 整数。
从下标 0 开始遍历 arr 中的每个下标 i ,并将包含整数 arr[i] 的 mat 单元格涂色。
请你找出 arr 中在 mat 的某一行或某一列上都被涂色且下标最小的元素,并返回其下标 i 。
示例 1
输入:arr = [1,3,4,2], mat = [[1,4],[2,3]]
输出:2
解释:遍历如上图所示,arr[2] 在矩阵中的第一行或第二列上都被涂色。
示例 2
输入:arr = [2,8,7,4,1,3,5,6,9], mat = [[3,2,5],[1,4,6],[8,7,9]]
输出:3
解释:遍历如上图所示,arr[3] 在矩阵中的第二列上都被涂色。
提示
m == mat.length
n = mat[i].length
arr.length == m * n
1 <= m, n <= 105
1 <= m * n <= 105
1 <= arr[i], mat[r][c] <= m * n
arr 中的所有整数 互不相同
mat 中的所有整数 互不相同
分析
使用一个频率数组frequency
array,然后预先记录每个值在mat矩阵中的位置信息。
然后遍历arr数组并使用预处理的位置递增相应的行和列频率。这里因为arr和mat数组中每个数都只出现一次,所以记录每个行出现的次数(频率),就是记录了所在行不同位置的出现次数。
所以,每次判断一下,如果行频率等于列数,反之亦然,则返回当前索引。
代码
class Solution {
public:
int firstCompleteIndex(vector<int>& arr, vector<vector<int>>& mat) {
int m = mat.size();
int n = mat[0].size();
// 记录元素位置
vector<pair<int,int>> pos(m*n+1, make_pair(0,0));
for(int i = 0; i < m; i ++)
{
for(int j = 0; j < n; j++)
{
pos[mat[i][j]] = make_pair(i,j);
}
}
vector<int> fre_row(m, 0); // 行出现频率数组
vector<int> fre_col(n, 0); // 列出现频率数组
int res = -1;
for(auto a = 0; a < arr.size(); a++)
{
// 行、列频率记录
int r = pos[arr[a]].first;
int c = pos[arr[a]].second;
fre_row[r] += 1;
fre_col[c] += 1;
// 如果行频率==列数 / 列频率==行数,则表明找到了
if (fre_row[r] == n || fre_col[c] == m)
{
res = a;
break;
}
}
return res;
}
};
题目链接
https://leetcode.cn/problems/first-completely-painted-row-or-column