1. 题目
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
2. 示例
示例:
现有矩阵 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。
3. 思路
3.1 蛮力法
遍历该二维数组,唯一可以优化的在开头比较一下,如果每一行的开头大于该数,则可以停止遍历,返回无。
3.2 减治法
- 该矩阵的特点:从上到下递增、从左到右递增。
- 性质:
- 左下角元素: 为所在列最大元素,所在行最小元素。
- 右上角元素: 为所在行最大元素,所在列最小元素。
将 matrix 中的左下角元素(标志数)记作 flag ,则有:
- 若 flag > target ,则 target 一定在 flag 所在行的上方,即 flag 所在行可被消去。
- 若 flag < target ,则 target 一定在 flag 所在列的右方,即 flag 所在列可被消去。
可以据此在每轮对比时消去一行(列)元素,以降低时间复杂度。
3.2.1 复杂度分析
- 时间复杂度 O(M+N)O(M+N) :其中,N 和 M 分别为矩阵行数和列数,此算法最多循环 M+N 次。
- 空间复杂度 O(1) : i, j 指针使用常数大小额外空间。
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
int i = matrix.length - 1, j = 0;
while(i >= 0 && j < matrix[0].length)
{
if(matrix[i][j] > target)//左下角大于,则从上一行开始找
i--;
else if(matrix[i][j] < target)//左下角小于,则右边列开始找
j++;
else
return true;
}
return false;
}
}