初试这个题目,以为简单,分分钟就能搞定。但还是超时了,是这么想的,既然是已经排序好的二维数组,何不转换成一维数组直接搞二分查找,这题目就O了嘛。还是想得太简单,对于一个二维数组,遍历全部元素那就得O(N^2)的时间复杂度,那坑定超时啊。
后来想想,也确实。我干嘛要转换成一维数组呢,直接当它是一维数组的不就好了,只要我找到中间数在二维数组中的下标,二分查找就so easy。
下面有超时的,和AC的两部分代码:
*
* 需求:
* 在一个m*n的矩阵中找到特定值
* 这个矩阵是有特点的:
* 1.矩阵的每一行都是从左到右排序过的;
* 2.每一行第一个整数都比上一行最后的数来得大。
*/
public class Search2DMatrix {
// /*
// * 转成一维数组后,二分查找
// *时间复杂度O(N)
// */
// public boolean searchMatrix(int[][] matrix, int target) {
// int m=matrix.length;
// int n=matrix[0].length;//m行,n列
// int counts=m*n;
//
// int[] tmp=new int[counts];
// int jishu=0;
// for(int i=0;i<m;i++)
// {
// for(int j=0;j<n;j++)
// {
// tmp[jishu]=matrix[i][j];
// jishu++;
// }
// }
// System.out.println(Arrays.toString(tmp));
// //调用二分查找
// return binarysearch(tmp,target);
//
// }
//binary search
public boolean binarysearch(int[] tmp,int target)
{
int low=0,high=tmp.length;
int mid;
while(low<high)
{
mid=(low+high)/2;
if(target<tmp[mid])
{
high=mid;
}
else if(target>tmp[mid])
{
low=mid;
}
else
return true;
}
return false;
}
}
AC的
/*
* 把这个二维数组当着一维数组,但是不做明显变换。
* 重点是如何找到中间数在二维数组中的下标
* 然后二分查找
*/
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix==null || matrix.length==0 || matrix[0].length==0)
return false;
int m = matrix.length;
int n = matrix[0].length;//矩阵m行n列
int start = 0;
int end = m*n-1;
while(start<=end){
int mid=(start+end)/2;
int midX=mid/n;
int midY=mid%n;//找到中间数的下标
if(matrix[midX][midY]==target)
return true;
if(matrix[midX][midY]<target){
start=mid+1;
}else{
end=mid-1;
}
}
return false;
}