题目1: 有序二维数组搜索
题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路
思路一:暴力算法
对数组中的每个元素依次遍历进行比较。
时间复杂度:O(N*N);
没有使用到:数组有序这个条件
/**
*
* @param target 待查询的目标
* @param array 二维数组
* @return
* 思路:遍历整个二维数组,穷举所有的目标进行比较
* 210ms 16784k
*/
public boolean Find1(int target, int [][] array) {
for(int i=0;i<array.length;i++){//遍历行
for(int j=0;j<array[0].length;j++){//遍历列
if(array[i][j]==target){
return true;
}
}
}
return false;
}
思路二:对每一行使用二分查找
因为每一行的数据为有序的,就是一个一维的有序数组,则可以对这行进行二分查找,时间复杂度为O(log2n)
则对n行依次使用二分查找,则时间复杂度为:O(nlogn)
//193ms
public static boolean Find4(int target,int[][] array){
for(int i=0;i<array.length;i++){//遍历每一行
int left = 0;
int right = array[0].length-1;
int mid = (left+right)/2;
while(left<=right){
mid = (left+right)/2;
if(array[i][mid]>target){//数组中的值比目标值大,则从左半部分再查找
right = mid-1;
}else if(array[i][mid]<target){
left=mid+1;
}else{
return true;//找到
}
}
}
return false;
}
思路三:从右上角或左下角比较进行指针变换
矩阵是有序的,
从左下角来看,向上数字递减,向右数字递增,
因此从左下角开始查找,当要查找数字比左下角数字大时。右移;
当 要查找数字比左下角数字小时,上移
从左下角下右上角依次比较
//212ms
public static boolean Find3(int target, int [][] array){
int i=array.length-1; //定义最后一行下标
int j =0;//左下角
while(i>=0 && j<array[0].length) {//
if (array[i][j] > target) {//左下角数字比待比较 数字 大上移
i--;
} else if (array[i][j] < target) {//左下角数字比当前数字小,右移
j++;
} else {
return true;
}
}
return false;
}
暴力算法: O(N*N) 210ms
行内二分查找: O(NLOGN)193ms
右下-左上: 212ms