题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
解题思路
由题目可知,该数组具备以下性质:从左到右升序,从上到下升序。把二维数组看成矩阵形式的话,也就是说每个元素比左边的元素大,比右边的元素小,比上边的元素大,比下边的元素下。因此可以得到这么一个结论:当整数A大于该数组中的元素B时,那么A必然不在B的上方,也不在B的左方,只需往B的下方和右方查找即可;当整数A小于该数组中的元素B时,那么A必然不在B的下方和右方,只需往B的上方和左方查找即可。
既然知道了数组的这个性质,那么该如何应用它呢?以下图数组为例,假如要寻找的数是n,惯性思维先试一下从左上角第一个元素1开始搜索,如果n比1大,根据刚才得到的数组性质:如果数组中存在n的话,他必然在1的右方或下方,往这两个方向搜索即可。但是这个结论并不能帮助我们,因为对于左上角元素来说,左方和下方都有元素,无法得知从哪个方向开始搜索。那么有没有下方和右方不同时存在元素或左方和上方不同时存在元素的的起始位置呢?显示从左下角和右上角两个位置的7和9符合。
以左下角元素7为例,
- n>7时:由于7位于第一列最底层且该数组向下递增,那么7是第一列最大的元素,因此n大于第一列所有元素,此时可以把第一列的元素全部排除,向右搜索即可(对应代码操作列数加1);
- n<7时,由于7位于最后一行最左边且该数组向右递增,那么7是最后一行中最小的元素,因此n小于最后一行所有的元素,此时可以把最后一行的元素全部排除,向上搜索即可(对应代码中操作行数减一)。
最坏的情况是要搜索的元素不在数组内,那么搜索到第一行的某个位置结束(搜索到第一行某个元素时,此时n小于该元素),或者最后一列的某个位置结束(搜索到最后一列某个元素时,此时n>该元素)。因此可以分析出该解法的时间复杂度是row+col(行数加列数)
代码
public class Solution {
public boolean Find(int target,int [][] array){
int row = array.length;
int col = array[0].length;
int i = row-1;
int j = 0;
while(i>=0 && j<col){
if(target>array[i][j]){
j++;
}else if(target<array[i][j]){
i--;
}else{
return true;
}
}
return false;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。