algorithm-base/animation-simulation/二分查找及其变种/二维数组的二分查找.md
2021-03-20 12:38:26 +08:00

3.7 KiB
Raw Blame History

二维数组

下面我们来看一下另外一种变体,如何在二维矩阵里使用二分查找呢?

其实这个很简单,只要学会了二分查找,这个完全可以解决,我们先来看一个例子

我们需要从一个二维矩阵中,搜索是否含有元素 7我们如何使用二分查找呢其实我们可以完全将二维矩阵想象成一个有序的一维数组然后用二分比如我们的二维矩阵中共有 9 个元素,那定义我们的 left = 0right = 9 - 1= 8是不是和一维数组定义相同然后我们求我们的 mid 值, mid = left +(right - left) >> 1此时 mid = 4 但是我们的二维矩阵下标最大是nums[2,2]呀,你这求了一个 4 ,让我们怎么整呀。如果我们理解了二分查找,那么这个题目考察我们的应该是如何将一维数组的下标,变为 二维坐标。其实也很简单,咱们看哈,此时咱们的 mid = 4咱们的二维矩阵共有 3行 3列那我们 mid =4肯定在第二行那么这个应该怎么求得呢?

我们可以直接用 mid/列数),即可,因为我们 mid = 44 /3 = 1,说明在 在第二行,那如果 mid = 7 7/3=2在第三行我们第几行知道了那么我们如何知道第几列呢我们可以直接根据 mid % 列数 )来求得呀,比如我们此时 mid = 77%3 = 1那么在我们一维数组索引为 7 的元素其处于二维数组的第2列大家看看下图是不是呀

二维数组

下面我们来看一下 leetcode 74题让我们给他整个通透

搜索二维矩阵

题目描述

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

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

示例1

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

示例2

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

示例3

输入matrix = [], target = 0 输出false

题目解析

在上面我们已经解释了如何在二维矩阵中进行搜索,这里我们再对其进行一个总结,就是我们凭空想象一个一维数组,这个数组是有二维数组一层一层拼接来的,也是完全有序,然后我们定义两个指针一个指向一维数组头部,一个指向尾部,我们求得 mid 值然后将 mid 变成二维坐标,然后和 target 进行比较,如果大于则移动 left ,如果小于则移动 right 。

动图解析

题目代码

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
           
           if (matrix.length == 0) {
               return false;
           }
           //行数
           int row = matrix.length;
           //列数
           int col = matrix[0].length;
           int left = 0;
           //行数乘列数 - 1右指针
           int right = row * col - 1;
           while (left <= right) {
               int mid = left+ ((right-left) >> 1);
               //将一维坐标变为二维坐标
               int rownum = mid / col;
               int colnum = mid % col;
               if (matrix[rownum][colnum] == target) {
                    return true;
               } else if (matrix[rownum][colnum] > target) {
                   right = mid - 1;
               } else if (matrix[rownum][colnum] < target) {
                   left = mid + 1;
               }
           }
           return false;
    }
}