题目描述:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路解析:
第一种暴力查找,可以用,但是没什么意思,因为这里的二维数组是递增的有序序列,所以我们还是考虑简化(动点脑子)的方法
方法2:
因为这个数组是一个有规律的数组,从左到右、 从上到下都是递增的一个顺序排序的,可以直接从右上角开始查找。
以这个数组为例:
如果我们要查找7这个key 值是否在这个二位数组中,从右上角开始,右上角是9,因为从上到下是递增的,而9是最后一列的结尾,所以7不可能出现在9这一列,就直接删除9这一列:
变成这样,然后根据新的二维数组,看右上角,是8同样的,从上到下递增,不可能是这一列,再删除这一列。
carry on,发现右上角是2,不再是大于7的数了,那么7只可能出现在2的下方,不可能在2的一行,所以删2这一行
同理,再删一行:
找到了,撒花完结。
总结一下:首先选中右上角的数字,如果正好找到就直接结束,如果右上角数字大于key,则删除列,如果右上角数字小于key ,则删除行,最终找到那个值。
代码实现:
static boolean find(int[][] a, int key) {
boolean found = false;
int n = a.length;// 得到二维数组的行
int m = a[0].length;// 得到二维数组的列数
// 那就从二维数组的右上角开始做筛选;
// 定义一个右上角点的坐标;
int row = 0;
int colum = m - 1;
while (row < n && colum >= 0) {// 只要没有到达左下角就继续做处理和运算
int temp = a[row][colum];
if (temp == key) {
found = true;
break;
} else if (key < temp) {
colum--;//如果该数字大于要查找的数字,就剔除这个数字所在的列
}
else if(temp<key) {
row++;//如果该数字小于查找的数字,就剔除这个数字所在的行
}
}
return found;
}
//测试代码
public static void main(String[] args) {
int[][] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
System.out.println(find(matrix, 100));
}
撒花完结。
** 总结**
除了右上角开始的查找以外,左下角的查找也应该可以,这个是一个对称的方法。
如果左下>key,则删除行,因为这一行后面的值>左下>key,如果左下小于key,则删除列,因为这一列上面的值<左下<key