✨个人主页:bit me
✨当前专栏:算法训练营
核心考点:数组相关,特性观察,时间复杂度把握 |
描述:
在一个二维数组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 <= 10^9
进阶:空间复杂度 O(1) ,时间复杂度 O(n+m)
示例1:
输入:7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:true
说明:存在7,返回true
示例2:
输入:1,[[2]]
返回值:false
示例3:
输入:3,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:false
说明:不存在3,返回false
思路:
这一题首先查找元素,我们首先想到的肯定是遍历数组,一个一个元素查找,这时候咱们的思路就被限制了,一次查找一个,效率极其低下,因此我们还得找一个更好的办法
代码实现:
if(array == null){
return false;
}
int i = 0;
int j = array[0].length - 1;
注意 i 是行,j 是列,其中 array[0].length - 1 是代表第一行的长度减去 1 ,就是第一行最后一个元素的下标,因为下标都是从 0 开始的。
while( i < array.length && j >= 0){
if(target < array[i][j]){//array[i][j]一定是当前行最大的,当前列最小的
//target < array[i][j] 排除当前列
j--;
}
else if(target > array[i][j]){
//target > array[i][j] 排除当前行
i++;
}
else{
//找到
return true;
}
}
return false;
- while 循环中的条件就是行 i 和列 j 都需要有合法性,i 是行,必须要有元素才可以,无论几行,j 是列,可以是一列及其以上,下标从 0 开始,所以大于等于 0 。
- 当查找的值小于右上角的值的时候,就可以把最右边的一列省去,因为从上往下递增,右上角最小
- 当查找的值大于右上角的值的时候,就可以把最上面的一行省去,因为从左往右递增,右上角最大
附上总的代码
public class Solution {
public boolean Find(int target, int [][] array) {
if(array == null){
return false;
}
int i = 0;
int j = array[0].length - 1;
while( i < array.length && j >= 0){
if(target < array[i][j]){//array[i][j]一定是当前行最大的,当前列最小的
//target < array[i][j] 排除当前列
j--;
}
else if(target > array[i][j]){
//target > array[i][j] 排除当前行
i++;
}
else{
//找到
return true;
}
}
return false;
}
}