二维数组中的查找
题意:在二维数组中,每一行都冲左到右递增。每一列都从上到下递增。输出一个二维数组和一个整数。判断数组中是否含有这个整数。
题解:
首先,我们来谈一下最为直观的解,就是遍历一遍二维数组,时间复杂度o(n*m),空间复杂度o(1)。当然这个时间复杂度是不足以拿offer的。我们再来看看时间复杂度为o(n),空间复杂度微o(1)的算法。
当我们需要解决一个比较复杂的问题时,一个很有效的办法就是从一个具体的问题入手,通过分析简单具体的例子,试图寻找普遍的规律。
针对这个问题呢,我们不妨也从具体的例子入手。假设array数组为:
1 2 8 9
2 4 8 12
4 7 10 13
6 8 11 15
我们寻找7。直接的想法从左上角开始找,1小于7.那么7肯定会在1的右边或者下边。这个时候有三个区域。右边区域,下边区域和右边与下边重叠的区域,不好确定接下来该怎么搞。我们再试试从左上角开始。9大于7,那么7就只能在9的左边,不可能在9在的当前列。那么可以排除9这一列。继续找左上角,是8。8大于7排除8在的当前列。继续找左上角2。发现2小于7,那么肯定在2的下面,排除2所在的当前行。继续找左上角,找到4,发现4小于7,排除4所在的当前行。继续左上角,发现是7.找到返回。该算法每次都能排除一行或者一列。所以时间复杂度是o(n+m),空间复杂度是o(1)。
根据题目的特点,从一个具体的案例去分析,找出优解。
class Solution {
public boolean Find(int target, int[][] array) {
if (array == null || array[0] == null) {
return false;
}
int rows = array.length;
int columns = array[0].length;
int currentRow = 0;
int currentColumn = columns - 1;
while ( currentRow < rows && currentColumn >= 0 ) {
if (array[currentRow][currentColumn] == target) {
return true;
}
if (array[currentRow][currentColumn] < target) {
++currentRow;
}else {
--currentColumn;
}
}
return false;
}
}
如果你有疑问,或者更优的代码,欢迎留言,相互学习。