题目描述
在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
数据范围:矩阵的长宽满足 0≤n,m≤500 , 矩阵中的值满足 0≤val≤109
进阶:空间复杂度 O(1) ,时间复杂度 O(n+m)
示例1
输入:
7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
输出:
true
示例2
输入:
3,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
输出:
false
题解:
此题可以使用暴力解法,双循环遍历数组查找目标值
但是由于此题为一个升序数组,那么我们可以使用二分查找。比如说此题可以先找到中间值 mid,他的下标为 index ,初始设定左边界为数组第一个数 left=0 ,右边界为数组长度 right=length-1 ,一定要在left小于等于right进入循环,这样目标值在最后一个的时候就也能找到。如果mid等于k的值,那么就直接返回true说明找到了。如果这个 mid 是大于k的,那么这个 mid 右边的数都是大于k,就让 right=index-1 ;否则就是 mid 小于 k,那么mid左边都是全小于k,那么就让left=index+1。循环外的返回值为false,说明没找到。
二分查找:
- 二分查找用于查找的内容逻辑上是需要有序的
- 查找的数量为一个而不是多个
对于满足这样的条件的我们可以使用二分查找。二分查找的思想就是用我们需要查找的值跟数组的 中间值去比较。
- 如果相等直接返回答案
- 如果不相等
- 如果中间的值大于目标值,则中间向右的值都大于目标值,全部排除
- 如果中间的值小于目标值,则中间向左的值都小于目标值,全部排除
public class Solution {
public static void main(String[] args) {
//Scanner scanner = new Scanner(System.in);
Solution s = new Solution();
int [][] arr = {{1,2,8,9},{2,4,9,12}};
System.out.println(s.Find(12,arr));
}
public boolean Find(int target,int[][] array){
for (int i = 0 ;i<array.length;i++){
if (binarySearch(array[i],target)){
return true;
}
}
return false;
}
public boolean binarySearch(int []arr,int k){
int left = 0;
int right = arr.length - 1;
while(left <= right){
int mid = (left + right) / 2;
if (arr[mid] == k) return true;
else if (arr[mid] > k) right = mid - 1;
else left = mid + 1;
}
return false;
}
}