题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
public class Solution {
public boolean Find(int target, int [][] array) {
}
}
我们可以理解为有一个二维数组,这个数组从左到右递增,从上到下递减,需要我们在这个二维数组中找到特定值targer。
我们可以有三种解法。
暴力法
我们单纯的去遍历整个数组,去查找targer。
//暴力法
public static boolean Find(int target, int [][] array) {
//处于严谨性,进行此类编程时最好先判断所传参数是否为空
if(array == null || array.length==0 || array[0].length==0){
return false;
}
//遍历每一个值
for(int i=0;i<array.length;i++){ //i表示所在行树
for(int j=0;j<array[0].length;j++){ //j表示所在列数
if(target==array[i][j]){ //判断是否存在值target
return true;
}
}
}
//遍历结束,没有发现target值,返回false
return false;
}
二分查找法
除了暴力法之外,我们可以思考更简单的方式,去优化我们每一行的查找。
对于数据量小的数组,两者区别不大,但是,但数据量大时,二分查找是一个更好的选择。
(二分查找是基于顺序存储结构,如果我们碰到顺序存储的结构时,不妨考虑一下二分查找)
//二分查找法
public static boolean Find(int target, int [][] array) {
//处于严谨性,进行此类编程时最好先判断所传参数是否为空
int m = array.length; //数组行数
int n = array[0].length; //数组列数
if(array == null || m==0 || n==0){
return false;
}
//逐行遍历
for(int i=0;i<m;i++){
//判断target是否可能存在于当前行
if(target >= array[i][0] && target <= array[i][n-1]){
//二分查找
int left=0; //定义左指针
int right = n-1; //定义右指针
while(left<=right){
System.out.println(left+""+right);
int mid = (right+left)/2; //中间值
if(target>array[i][mid]){
left=mid+1;
}
else if(target<array[i][mid]){
right=mid-1;
}
else{
return true;
}
}
}
}
//遍历结束,没有发现target值,返回false
return false;
}
从左下(右上)查找
当我们拿到这个题目时,第一想法肯定是从左上角开始查找,但我们发现我们无法控制数组下标,因为从左到右,从上到下都是递增的,所以我们开始思考是否存在一个方向使得数组横纵方向上一个递增,一个递减,从而控制数组下标进行查找。
于是,我们就有了从从左下(右上)查找的思路。
建议:做这类题时先进行思考,当有一个想法时,按照自己的思路进行下去,如果发现自己的思路存在问题,先试着改进自己的思路,多思考,多尝试,养成一种发现问题、解决问题的思维方法。对于以后的发展将会很有帮助。
/* 利用二维数组由上到下,由左到右递增的规律,
那么选取左下角或者右上角的元素a[row][col]与target进行比较,
当target小于元素a[row][col]时,那么target必定在元素a所在行的上边,
即row--;
当target大于元素a[row][col]时,那么target必定在元素a所在列的右边,
即col++;
*/
//从左下开始查找
public static boolean Find(int target, int [][] array) {
//处于严谨性,进行此类编程时最好先判断所传参数是否为空
if (array == null || array.length == 0 ||
(array.length == 1 && array[0].length == 0))
return false;
//从数组的左下角开始查找,找到左下角元素坐标
int row = array.length-1;
int col = 0;
//开始遍历
while(row >= 0 && col <= array[0].length-1){
//当target小于元素a[row][col]时,那么target必定在元素a所在行的上边,即row--;
if (target < array[row][col]){
row--;
}
//当target大于元素a[row][col]时,那么target必定在元素a所在列的右边,即col++;
else if(target > array[row][col]){
col++;
}
//找到目标,返回true
else{
return true;
}
}
//遍历结束,没有发现target值,返回false
return false;
}