LeetCode 1380. 矩阵中的幸运数
给你一个 m * n 的矩阵,矩阵中的数字 各不相同 。请你按 任意 顺序返回矩阵中的所有幸运数。
幸运数 是指矩阵中满足同时下列两个条件的元素:
在同一行的所有元素中最小
在同一列的所有元素中最大
示例 1:
输入:matrix = [[3,7,8],[9,11,13],[15,16,17]]
输出:[15]
解释:15 是唯一的幸运数,因为它是其所在行中的最小值,也是所在列中的最大值。
m == mat.length
n == mat[i].length
1 <= n, m <= 50
1 <= matrix[i][j] <= 10^5
矩阵中的所有元素都是不同的
解法一:直接模拟:
class Solution {
public:
vector<int> luckyNumbers(vector<vector<int>>& matrix) {
int rowNum = matrix.size();
int colNum = matrix[0].size();
vector<int> ans;
for (int row = 0; row < rowNum; ++row) {
for (int col = 0; col < colNum; ++col) {
int i = 0;
for (; i < rowNum; ++i) {
if (matrix[i][col] > matrix[row][col]) {
break;
}
}
if (i != rowNum) {
continue;
}
i = 0;
for (; i < colNum; ++i) {
if (matrix[row][i] < matrix[row][col]) {
break;
}
}
if (i != colNum) {
continue;
}
ans.push_back(matrix[row][col]);
}
}
return ans;
}
};
如果矩阵有n行m列,此算法时间复杂度为O(mn(m+n)),空间复杂度为O(1)。
解法二:先找出每一行的最小值和每一列的最大值,然后遍历矩阵,看当前遍历到的值是否是幸运数:
class Solution {
public:
vector<int> luckyNumbers(vector<vector<int>>& matrix) {
int rowNum = matrix.size();
int colNum = matrix[0].size();
vector<int> maxCol(colNum), minRow(rowNum, INT_MAX);
for (int row = 0; row < rowNum; ++row) {
for (int col = 0; col < colNum; ++col) {
maxCol[col] = max(matrix[row][col], maxCol[col]);
minRow[row] = min(matrix[row][col], minRow[row]);
}
}
vector<int> ans;
for (int row = 0; row < rowNum; ++row) {
for (int col = 0; col < colNum; ++col) {
if (matrix[row][col] == maxCol[col] && matrix[row][col] == minRow[row]) {
ans.push_back(matrix[row][col]);
}
}
}
return ans;
}
};
如果矩阵有n行m列,此算法时间复杂度为O(mn),空间复杂度为O(m+n)。
解法三:如果存在幸运数,则幸运数有两个性质:
1.只有一个幸运数:对于一个幸运数来说,本行中其他元素都比它大,本列中其他元素都比它小,因此最多只可能出现一个幸运数。如果幸运数为0,则幸运数所在行的数都大于0,所在列的数都小于0,假如有第二个幸运数,由于幸运数需要是本行中最小的数,因此它必须小于本行中第一个幸运数所在列的数,即要小于一个负数,又由于幸运数需要是本列中最大的数,因此它必须大于本列中第一个幸运数所在行的数,即还要大于一个正数,这是不可能的。
2.接1中的假设,由于与幸运数同列的除幸运数外的所有数字都是负数,因此所有每行的最小值
中,幸运数所在行是最大的(其他都是负的,幸运数所在行的最小值为0);又由于与幸运数同行的除幸运数外的所有数字都是正数,因此所有每列的最大值中
,幸运数所在列是最小的(其他都是正的,幸运数所在列最大值为0),因此幸运数是每列的最大值中
最小的,是每行的最小值
中最大的。
因此我们可以遍历一遍矩阵,找出所有每行的最小值
中最大的值,如果存在幸运数,就是该值,我们再看此数是否是所在列的最大值,如果是,则该数就是幸运数,否则幸运数不存在:
class Solution {
public:
vector<int> luckyNumbers(vector<vector<int>>& matrix) {
int rowNum = matrix.size();
int colNum = matrix[0].size();
int rowMax = 0, k = -1;
for (int row = 0; row < rowNum; ++row) {
// 找出本行中的最小值
int curMinIdx = min_element(matrix[row].begin(), matrix[row].end()) - matrix[row].begin();
// 找出`每行的最小值`中的最大值,并记录其所在列
if (matrix[row][curMinIdx] > rowMax) {
rowMax = matrix[row][curMinIdx];
k = curMinIdx;
}
}
if (k == -1) {
return {};
}
// 看`每行的最小值`中的最大值在其所在列中是否是最大值
for (int row = 0; row < rowNum; ++row) {
if (matrix[row][k] > rowMax) {
return {};
}
}
return {rowMax};
}
};
如果矩阵有n行m列,此算法时间复杂度为O(mn),空间复杂度为O(1)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2021-02-20 MySQL必知必会 学习笔记 第十一章 使用数据处理函数
2019-02-20 JAVA中的算术运算符
2019-02-20 JAVA数据类型转换