Java教程

面试算法题 寻找矩阵的极小值

本文主要是介绍面试算法题 寻找矩阵的极小值,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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};
    }
};
这篇关于面试算法题 寻找矩阵的极小值的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!