力扣第七十四题-搜索二维矩阵

142 阅读2分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

前言

力扣第七十四题 搜索二维矩阵 如下所示:

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

  • 每行中的整数从左到右按升序排列。
  • 每行的第一个整数大于前一行的最后一个整数。

 

示例 1:

输入: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出: true

示例 2:

输入: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出: false

一、思路

既然要高校查找到有规律的矩阵中是否含有目标值,那么首先想到的肯定是二分法了。

因为矩阵每一行是从左至右递增的,而每一列也是递增的,且下一行的值一定会大于上一行的值,这是非常契合二分查找的。如下图所示:

image.png

我们为什么不把这个二维数组想象成一个递增的一维数组呢?那么问题就变成了在一个递增的一位数组中查找是否含有目标值?

既然想法有了,那么难题就变成了如何将二维数组的坐标映射成一维数组?其实这个也很简单,matrix[i][j] 这个位置就相当于一维数组中的 arr[j + i * colLen]

例如 matrix[][] 的大小为 3 x 4 转换成一维数组则为 arr[] 大小为 12
那么 matrix[2][2] 相当于一维数组中的 arr[10]

image.png

同理 arr[i] 相当于二维数组 matrix[i/colLen][i%colLen]

二、实现

实现代码

实现代码与思路中保持一致

    public boolean searchMatrix(int[][] matrix, int target) {
        int rowLen = matrix.length; // 行高
        int colLen = matrix[0].length;    // 列长
        int left = 0;
        int right = rowLen * colLen - 1;
        while (left <= right) {
            int mid = (right + left) / 2;
            // mid/colLen 表示在第几行
            int x = matrix[mid/colLen][mid%colLen];
            if (x < target) {
                left = mid + 1;
            } else if (x > target) {
                right = mid - 1;
            } else {
                // 如果等于,直接返回true
                return true;
            }
        }
        return false;
    }

测试代码

    public static void main(String[] args) {
        int[][] matrix = {{1,3,5,7},{10,11,16,20},{23,30,34,60}};
        new Number74().searchMatrix(matrix, 3);
    }

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~