面试算法题 寻找矩阵的极小值
AcWing 1452. 寻找矩阵的极小值
给定一个 n×n 的矩阵,矩阵中包含 n×n 个 互不相同 的整数。
定义极小值:如果一个数的值比与它相邻的所有数字的值都小,则这个数值就被称为极小值。
一个数的相邻数字是指其上下左右四个方向相邻的四个数字,另外注意,处于边界或角落的数的相邻数字可能少于四个。
要求在 O(nlogn) 的时间复杂度之内找出任意一个极小值的位置,并输出它在第几行第几列。
本题中矩阵是隐藏的,你可以通过我们预设的 int 函数 query 来获得矩阵中某个位置的数值是多少。
例如,query(a,b) 即可获得矩阵中第 a 行第 b 列的位置的数值。
注意:
矩阵的行和列均从 0 开始编号。
query()函数的调用次数不能超过 (n+2)×⌈log2n⌉+n。
答案不唯一,输出任意一个极小值的位置即可。
数据范围
1≤n≤300,矩阵中的整数在int范围内。
输入样例:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
输出样例:
[0, 0]
代码
// Forward declaration of queryAPI.
// int query(int x, int y);
// return int means matrix[x][y].
//不能行列二分,行列二分的答案不一定正确
// 主要思想是用二分的方法进行列查找,对每列找到最小值,判单这个最小值左右两个数是否能让该数满足矩阵极小值,如果不能排除掉一半的列
class Solution {
public:
vector<int> getMinimumValue(int n) {
typedef long long LL;
const LL INF = 1e15;
int l = 0, r = n -1;
while (l < r){
int mid = l + r >> 1;//去mid列
int k;//记录列里面最小值的位置
LL val = INF;//取最小值过程中可能会爆int, 取LL
//查找列里面最小值
for (int i = 0; i < n; i ++){
int t = query(i,mid);
if(t < val){
val = t;
k = i;
}
}
LL left = mid ? query(k, mid -1) :INF;// 特判下mid是不是边界
LL right = mid + 1 < n ? query(k, mid + 1):INF;
// 进行mid判断,可以筛掉一半的列
if(val < left && val < right) return {k,mid};
if(left < val) r = mid - 1;
else l = mid + 1;
}
//得到最后r==l ,找该列中最小值即符合条件
int k;
LL val = INF;
for (int i = 0; i < n; i ++){
int t = query(i, r);
if(t < val){
val = t;
k = i;
}
}
return {k,r};
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix