汇总:剑指offer算法合集
题目
在一个 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof
解题思路
- 由于从左到右递增,从上到下也递增,说明同一行右边始终比左边大,同一列下面始终比上面大,因此查找的时候可以根据这个特性进行移动下标
- 根据上面的特性,我们可以寻找一个位置,用来作为查找起点,可能是矩阵的四个角落,我们一一分析:
- 从左上角开始查找,向左或者向下都是递增,我们无法得知下一步走向,out
- 从右上角开始查找,向左是递减,向下递增,可以根据大小得知下一步走向,get
- 从左下角开始查找,向上是递减,向右是递增,可以根据大小得知下一步走向,get
- 从右下角开始查找,向左是递减,向上减,我们无法得知下一步走向,out
- 由上面分析得知,从右上角和左下角开始遍历都是可以的
- 这里我们选择从右上角开始查找,走到某一个位置时,有以下几种情况:
- 如果当前所在位置的值比目标值大,则向左一步
- 如果当前所在位置的值比目标值小,则向下一步
- 如果相等,则返回当前值
- 如果超出最左边的边界,或者最下边的边界,则不存在目标值
复杂度分析
向下和向左查找,最多查找m+n次,因此时间复杂度为O(m+n)
,需要常数级空间,空间复杂度为O(1)
代码实现
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
//数组为空或者m n为0时,必定不存在目标值,判空也防止空异常
if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
return false;
//从右上角开始查找
int i = 0, j = matrix[0].length - 1;
//不能超过左边界和下边界
while (i < matrix.length && j >= 0) {
//当前值小于目标值,向下移动一步
if (matrix[i][j] < target) i++;
//当前值大于目标值,向左移动一步
else if (matrix[i][j] > target) j--;
//当前值等于目标值,返回true
else return true;
}
//找不到目标值,返回false
return false;
}
}