二维数组的查找
描述
在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[ [1,2,8,9], [2,4,9,12], [4,7,10,13], [6,8,11,15] ]
给定 target = 7,返回 true。 给定 target = 3,返回 false。
0 <= array.length <= 500
0 <= array[0].length <= 500
解法一 暴力遍历算法
解法二 时间复杂度 O(nlog2n)
public boolean Find(int target, int [][] array) {
int width=array.length; //宽度
int length=array[0].length; //长度
if(width==0||length==0||target>array[width-1][length-1]||target<array[0][0]){
return false;
}
for(int i=0;i<width;i++){
int left=0;
int right=width-1;
while(left<=right){
int mid=(left+right)/2;
if(target>array[i][mid]){
left=mid+1;
break;
}
if(target<array[i][mid]){
right=mid-1;
break;
}
return true;
}
}
return false;
}
解法三 新思路二分法(以左下角或右上角为起始)
arr | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
0 | < | < | < | < | val |
1 | |||||
2 | |||||
3 | tar | ||||
4 |
1)我么设初始值为右上角元素,arr[0] [5] = val,目标tar = arr[3] [1]
2)接下来进行二分操作:
3)如果val == target,直接返回
4)如果 tar > val, 说明target在更大的位置,val左边的元素显然都是 < val,间接 < tar,说明第 0 行都是无效的,所以val下移到arr[1] [5]
5)如果 tar < val, 说明target在更小的位置,val下边的元素显然都是 > val,间接 > tar,说明第 5 列都是无效的,所以val左移到arr[0] [4]
6)继续步骤2)
时间复杂度:O(m+n) ,其中m为行数,n为列数,最坏情况下,需要遍历m+n次。
空间复杂度:O(1)
public class Solution {
public boolean Find(int target, int [][] array) {
int length=array[0].length;
int width=array.length;
if(length==0||width==0||array[0][0]>target||array[width-1][length-1]<target){
return false;
}else{
int i=0;
int j=length-1
while(i<width&&j>0){
int val=array[i][j];
if(val==target){
return true;
}else if(val>target){
j--;
}else if(val<target){
i++;
}
}
}
return false;
}
}