题目
在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例
解题思路
排好序的数组,二分查找
代码
package 剑指offer.查找问题.offer4;
public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
// int[][] 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}
// };
//
// int[][] 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}};
int[][] matrix = {{5}};
int target = 5;
solution.findNumberIn2DArray(matrix,target);
}
/**
* 思路分析
* 对于存在递增的序列,我们采用二分法进行查找
*
*
* 先对于纵坐标进行查找,查找到对应的值后,然后对于横向进行二分查找
*
* 注意:纵坐标横向查找到了,但是0-查找到的top值区间的,数组都需要进行二分查找,看是否存在对应的值
*
* @param matrix
* @param target
* @return
*/
public boolean findNumberIn2DArray(int[][] matrix, int target) {
int height = matrix.length;
int width = matrix[0].length;
int top = findHeight(0, height-1, matrix, target);
for (int i = 0; i <= top; i++) {
boolean res = findX(0, width-1, matrix[i], target);
if(res){
return true;
}
}
return false;
}
public int findHeight(int top,int bottom,int[][] matrix, int target){
if(top >= bottom){
return bottom;
}
int index = (top+bottom)/2;
int indexNum = matrix[index][0];
if(indexNum == target){
return index;
}
if(indexNum < target){
return findHeight(index+1,bottom,matrix,target);
}else{
return findHeight(top,index-1,matrix,target);
}
}
public boolean findX (int left,int right,int[] matrix, int target){
if(left > right){
return false;
}
int index = (left+right)/2;
int indexNum = matrix[index];
if(indexNum == target){
return true;
}
if(indexNum < target){
return findX(index+1, right, matrix, target);
}else{
return findX(left,index-1,matrix,target);
}
}
}