今天分享的题目来源于 LeetCode 上的剑指 Offer 系列 04 . 二维数组中的查找。
题目链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/
更多题目动画讲解:https://www.algomooc.com
一、题目描述
在一个 n * m
的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
限制:
- 0 <= n <= 1000
- 0 <= m <= 1000
二、题目解析
仔细观察矩阵,可以发现:左下角元素 为所在列最大元素,所在行最小元素
如果 左下角元素 大于了目标值,则目标值一定在该行的上方, 左下角元素 所在行可以消去。
如果 左下角元素 小于了目标值,则目标值一定在该列的右方, 左下角元素 所在列可以消去。
具体操作为从矩阵左下角元素开始遍历,并与目标值对比:
- 当
matrix[i][j] > target
时: 行索引向上移动一格(即i--
),即消去矩阵第i
行元素; - 当
matrix[i][j] < target
时: 列索引向右移动一格(即j++
),即消去矩阵第j
列元素; - 当
matrix[i][j] == target
时: 返回 true。 - 如果越界,则返回 false。
三、动画描述
四、图片描述
![v2-a9617925a1fbad00acf2d41198085c3a_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/fa2bdcce2541bbe8901379217fc8ab0a.png)
![v2-ad0ec95ff08e9c361b3217f3bca09b9c_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/835f3c8f221d3a761cba2666ebbb496c.jpeg)
![v2-907bb6ab936644ccbe1c8b67db9f3c01_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/fefe81462179b2348a088e95632dab46.jpeg)
![v2-f147124d851de352db515c99de4aef5f_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/e99bd84761b2a54a2ddfcafb5c82e354.jpeg)
![v2-03ff4a68d9998031414ae5ed493c4660_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/40cc7229c09c54c8e829f2cd12592757.jpeg)
![v2-e2af4ebbb6b1f738c0c42ccc474d2f00_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/82b6fe82c9ade6627b55ed9c582e356c.jpeg)
![v2-9a7ef2624a266e08a42ff1d8013556ac_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/994834c5c0a5cb6dd27c7e3e6a1407b2.jpeg)
![v2-f40dad41562a96e9057f7d03ee97d0a3_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/4f578ef9cbaddc4f4d2c419a3abd3544.jpeg)
![v2-dc82a5792789e27b924ef45c50428ec1_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/2b69e9ca2b185df9dddbe74b2e2214dc.jpeg)
![v2-13f8fe19e090dce9052588b85535b0c5_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/00a918e9bb722c32385145651599f2ea.jpeg)
![v2-4fe59901d918541fff0d1054f828040f_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/e8ed603fbf401f47322563fb78dd4186.jpeg)
![v2-ab25127a9d7b984e7f2628b76fcc15f5_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/93ccb41b26ea6490e4900a70866e6bb4.jpeg)
![v2-18af0f7922400a9bee695236b3eec22a_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/61a8a79eda37dda4b8c73baf98cef97d.png)
![v2-3b7c8fc05ffa3bcfe4e567da3582ab6c_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/9ff0cd410b9f5b3345bb5f3441a75e4a.jpeg)
![v2-3ee4a49fa394d9b52f5a64e5e084f6c3_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/d6052b91de648c72e9e10a7c0d706107.jpeg)
![v2-2585bc9834ab5849e62b31d3552e6472_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/4d0e924eb82afe51fbd340e19efa5b3d.png)
![v2-d797414ebeb4eed3b1d231d0bd5bc2be_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/4a674907d256222bf5fe2c1fee1d99fb.png)
![v2-1228b1aca2adc1db6d48a26a7052f27f_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/d19d48e7e05ad65614637fe5da060fdd.jpeg)
![v2-df73125b641534937cf549593ff513ef_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/f7b484c8bd1cbf6a22b28e18d75bfa27.jpeg)
五、参考代码
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
//初始化 i 和 j 为数组左下角元素
int i = matrix.length - 1,
int j = 0;
//如果 i 和 j 没有越界继续判断
while(i >= 0 && j < matrix[0].length){
if(matrix[i][j] > target){
//行索引向上移动一格(即 i-- ),即消去矩阵第 i 行元素
i--;
}else if(matrix[i][j] < target){
//列索引向右移动一格(即 j++ ),即消去矩阵第 j 列元素
j++;
}else{
//找到目标值,直接返回 ture
return true;
}
}
//没有找到目标值,返回 false
return false;
}
}
六、复杂度分析
时间复杂度
时间复杂度为 O(M+N),其中,N 和 M 分别为矩阵行数和列数,此算法最多循环 M + N 次。
空间复杂度
空间复杂度为 O(1)。
七、相关标签
- 数组
- 双指针
- 二分法
更多题目动画讲解:
AlgoMooc-一个专属于程序员的平台,和大家一起刷题