algorithm-base/animation-simulation/二分查找及其变种/二维数组的二分查找.md

113 lines
5.2 KiB
Java
Raw Normal View History

2021-07-23 15:44:19 +00:00
> 如果阅读时发现错误或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
2021-03-20 09:16:07 +00:00
>
> 感谢支持该仓库会一直维护希望对各位有一丢丢帮助
>
2021-07-23 15:44:19 +00:00
> 另外希望手机阅读的同学可以来我的 <u>[**公众号袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
2021-03-20 09:16:07 +00:00
2021-07-23 15:44:19 +00:00
#### [74. 搜索二维矩阵](https://leetcode-cn.com/problems/search-a-2d-matrix/)\*\*\*\*
2021-03-18 05:33:53 +00:00
下面我们来看一下另外一种变体如何在二维矩阵里使用二分查找呢
其实这个很简单只要学会了二分查找这个完全可以解决我们先来看一个例子
2021-07-23 15:44:19 +00:00
我们需要从一个二维矩阵中搜索是否含有元素 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肯定在第二行那么这个应该怎么求得呢?
2021-03-18 05:33:53 +00:00
2021-07-23 15:44:19 +00:00
我们可以直接用 mid/列数即可因为我们 mid = 44 /3 = 1,说明在 在第二行那如果 mid = 7 7/3=2在第三行我们第几行知道了那么我们如何知道第几列呢我们可以直接根据 mid % 列数 来求得呀比如我们此时 mid = 77%3 = 1那么在我们一维数组索引为 7 的元素其处于二维数组的第 2 大家看看下图是不是呀
2021-03-18 05:33:53 +00:00
![二维数组](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/二维数组.63nd4jlj0v00.png)
2021-07-23 15:44:19 +00:00
下面我们来看一下 leetcode 74 让我们给他整个通透
2021-03-18 05:33:53 +00:00
### 搜索二维矩阵
#### 题目描述
编写一个高效的算法来判断 m x n 矩阵中是否存在一个目标值该矩阵具有如下特性
每行中的整数从左到右按升序排列
每行的第一个整数大于前一行的最后一个整数
2021-07-23 15:44:19 +00:00
示例 1
2021-03-18 05:33:53 +00:00
> 输入matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,50]], target = 3
> 输出true
2021-07-23 15:44:19 +00:00
示例 2
2021-03-18 05:33:53 +00:00
> 输入matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,50]], target = 13
> 输出false
2021-07-23 15:44:19 +00:00
示例 3
2021-03-18 05:33:53 +00:00
> 输入matrix = [], target = 0
> 输出false
#### 题目解析
2021-07-23 15:44:19 +00:00
在上面我们已经解释了如何在二维矩阵中进行搜索这里我们再对其进行一个总结就是我们凭空想象一个一维数组这个数组是有二维数组一层一层拼接来的也是完全有序然后我们定义两个指针一个指向一维数组头部一个指向尾部我们求得 mid 值然后将 mid 变成二维坐标然后和 target 进行比较如果大于则移动 left 如果小于则移动 right
2021-03-18 05:33:53 +00:00
动图解析
![](https://img-blog.csdnimg.cn/20210318133244216.gif)
#### 题目代码
```java
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
2021-07-23 15:44:19 +00:00
2021-03-18 05:33:53 +00:00
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;
}
}
```
2021-07-27 18:26:32 +00:00
Go Code:
```go
func searchMatrix(matrix [][]int, target int) bool {
if len(matrix) == 0 {
return false
}
row, col := len(matrix), len(matrix[0])
// 将二维数组拉平为一维。
l, r := 0, row * col - 1
for l <= r {
m := l + (r - l) / 2
// 将一维的坐标转换为二维
x, y := m / col, m % col
if matrix[x][y] == target {
return true
} else if matrix[x][y] < target {
l = m + 1
} else if matrix[x][y] > target {
// 二分查找时把所有的情况都要写出来避免直接else
r = m - 1
}
}
return false
}
```