二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
分析:
首先,对于查找,我们最先能想到的就是遍历数组,挨个进行比较,但是效率是非常低的,最坏的时间复杂度是 O(n2),所以我们必须去优化它。**查找其实也就是排除的过程,只要排除的越多,说明效率越高,**像挨个遍历,每一次只能排除一个,所以效率低,题目中的二维数组是有规律的,例如要在下面的二维数组中查找数字 6
1, 3, 5
2, 4, 7
3, 6, 8
我们可以选择左下角的 3 或者右上角的 5 作为第一个比较的元素,这里以右上角为例
-
我们将目标值 6,和右上角的 5 比较,右上角的值小于目标值,说明右上角这一行都不会有和目标值相等的,因为二维数组的每一行都是递增的,5 已经是这一行最大的元素,这样我们就排除了一行,接下来只需要在
2, 4, 7 3, 6, 8
中查找就行了
-
继续比较右上角的 7 和目标值 6,7 > 6,所以 7 所在的这一列都不会有和目标值相等的,所以我们可以排除这一列
2, 4 3, 6
-
继续和右上角 4,进行比较,基准值大于 4,所以可以排除这一行
3, 6
-
比较和右上角相等,找到,返回 true
我们可以看出,这样的查找,每一次排除的都是一行或者一列,所以效率明显比遍历数组快
源代码
public boolean Find(int[][] array, int target) {
// 行下标
int i = 0;
// 列下标
int j = array[0].length - 1;
while (i < array.length && j >= 0){
// 右上角的值和目标值相等
if (array[i][j] == target){
return true;
// 目标值小于右上角的值
}else if (array[i][j] > target){
// 排除这一列
j--;
}else { // 目标值大于右上角的值
// 排除这一行
i++;
}
}
return false;
}