LeetCode 2373. 矩阵中的局部最大值
给你一个大小为 n x n 的整数矩阵 grid 。
生成一个大小为 (n - 2) x (n - 2) 的整数矩阵 maxLocal ,并满足:
maxLocal[i][j] 等于 grid 中以 i + 1 行和 j + 1 列为中心的 3 x 3 矩阵中的 最大值 。
换句话说,我们希望找出 grid 中每个 3 x 3 矩阵中的最大值。
返回生成的矩阵。
示例 1:
输入:grid = [[9,9,8,1],[5,6,2,6],[8,2,6,4],[6,2,2,2]]
输出:[[9,9],[8,6]]
解释:原矩阵和生成的矩阵如上图所示。
注意,生成的矩阵中,每个值都对应 grid 中一个相接的 3 x 3 矩阵的最大值。
n == grid.length == grid[i].length
3 <= n <= 100
1 <= grid[i][j] <= 100
法一:直接遍历即可,时间复杂度O(n 2 ^2 2),空间复杂度O(1):
class Solution {
public:
vector<vector<int>> largestLocal(vector<vector<int>>& grid) {
vector<vector<int>> ret;
int rowNum = grid.size();
int colNum = grid[0].size();
for (int i = 0; i < rowNum - 2; ++i) {
ret.emplace_back();
for (int j = 0; j < colNum - 2; ++j) {
int max = 0;
int rowStart = i;
int rowEnd = i + 2;
int colStart = j;
int colEnd = j + 2;
for (int curRow = rowStart; curRow <= rowEnd; ++curRow) {
for (int curCol = colStart; curCol <= colEnd; ++curCol) {
if (grid[curRow][curCol] > max) {
max = grid[curRow][curCol];
}
}
}
ret[i].push_back(max);
}
}
return ret;
}
};
法二:法一过程中有些数值是被重复计算的,我们可以先算出所有三行一列的单元中最大值,每次只取这三个单元的最大值的最大值即可,但这样做时间复杂度还是O(n 2 ^2 2),只有常数级优化,空间复杂度也增长到O(n 2 ^2 2),只有对时间极度敏感且空间较充足时才有意义:
class Solution {
public:
vector<vector<int>> largestLocal(vector<vector<int>>& grid) {
vector<vector<int>> ret;
int rowNum = grid.size();
int colNum = grid[0].size();
vector<vector<int>> tmpMax;
for (int tmpRow = 0; tmpRow < rowNum - 2; ++tmpRow) {
tmpMax.emplace_back();
for (int tmpCol = 0; tmpCol < colNum; ++tmpCol) {
int unitMax = max(grid[tmpRow][tmpCol],
max(grid[tmpRow + 1][tmpCol],
grid[tmpRow + 2][tmpCol]));
tmpMax[tmpRow].push_back(unitMax);
}
}
for (int i = 0; i < rowNum - 2; ++i) {
ret.emplace_back();
for (int j = 0; j < colNum - 2; ++j) {
int rowIndex = i;
int colIndex = j;
int maxNum = max(tmpMax[rowIndex][colIndex],
max(tmpMax[rowIndex][colIndex + 1],
tmpMax[rowIndex][colIndex + 2]));
ret[i].push_back(maxNum);
}
}
return ret;
}
};
法三:法二中,tmpMax只需要1*n的大小即可,因为每下一行可以复用前一行,从而进一步把空间复杂度降低为O(n):
class Solution {
public:
vector<vector<int>> largestLocal(vector<vector<int>>& grid) {
vector<vector<int>> ret;
int rowNum = grid.size();
int colNum = rowNum;
vector<int> tmpMax(colNum, 0);
for (int i = 0; i < rowNum - 2; ++i) {
ret.emplace_back();
for (int curCol = 0; curCol < rowNum; ++curCol) {
tmpMax[curCol] = max(grid[i][curCol], max(grid[i + 1][curCol], grid[i + 2][curCol]));
}
for (int j = 0; j < colNum - 2; ++j) {
int colIndex = j;
int maxNum = max(tmpMax[colIndex], max(tmpMax[colIndex + 1], tmpMax[colIndex + 2]));
ret[i].push_back(maxNum);
}
}
return ret;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人