leetcode-搜索二维矩阵

124 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

本周继续顺着前几天的思路刷二分法的题目,先把简单和中等的全部做完,再去挑战困难的。

题目描述

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

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

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

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

思路

这题相对于最基础的二分搜索,有一个小变化,就是数组从一维变成了二维。不过根据这个矩阵的特点,我们可以把这个二维的矩阵转化成为一个一维数组。
对于示例1中的矩阵,我们把数据打平成一个一维数组的话,应该是这样的顺序:num[0][0]、num[0][1]、num[0][2]、num[0][3]、num[1][0]、num[1][1]、num[1][2]、num[1][3]、num[2][0]、num[2][1]、num[2][2]、num[2][3];不难发现,其实这个下标的顺序,就是对应一个4进制的数,转为10进制,就是我们熟悉的0~11。推广到m*n的矩阵,其实可以把下标看成n进制的数据,就是使用一个数来标示2维的2个下标。同样的,如果有一个10进制的数值,我们也可以转换出来2维的下标。通过这一次转换,我们可以把原始的二维矩阵转换成一维的数组,就是我们常见的二分查找问题了。

Java版本代码

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length;
        int n = matrix[0].length;
        int left = 0, right = m*n-1;
        while (left <= right) {
            int mid = left + (right-left)/2;
            int x = mid/n;
            int y = mid%n;
            if (target == matrix[x][y]) {
                return true;
            } else if (target < matrix[x][y]) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return false;
    }
}