剑指offer学习(Java)——面试题4:二维数组中的查找

    题目:在一个二维数组中,每一行都是按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

    当然可以直接遍历数组,那么时间复杂度就是O(m*n),要充分利用数组行有序和列有序的特点。一维数组有序时查找可以用二分查找,其时间复杂度是O(logn)。

这里也尝试二分查找,首先选取二维数组中的一个数字,

若这个数小于要查找的数字,那么待查找的数字只可能出现在右边的所有列或者下面的所有行,

若这个数大于要查找的数字,那么待查找的数字只可能出现在左边的所有列或者上面的所有行。


但是这样就有两个区域,而且有重叠,

我们换一下选取数字的位置,

左上角和右下角于事无补,

左下角

    若这个数小于要查找的数字,那么待查找的数字只可能出现在右边的所有列,剔除当前列,重复之前的操作,继续判断

    若这个数大于要查找的数字,那么待查找的数字只可能出现在上面的所有行,剔除当前行,重复之前的操作,继续判断

右上角

    若这个数小于要查找的数字,那么待查找的数字只可能出现在下面的所有行,剔除当前行,重复之前的操作,继续判断

    若这个数大于要查找的数字,那么待查找的数字只可能出现在左边的所有列,剔除当前列,重复之前的操作,继续判断

选取左下角的代码如下

public class Solution {
    public boolean Find(int target, int [][] array) {
        int hang = array.length;
        int lie = array[0].length;
        for(int i=hang-1,j = 0;i>=0&&j<lie;){
        	if(target == array[i][j]) return true;
            else if(target > array[i][j]) {j++;continue;}
            else {i--;continue;}
        }
        return false;
    }
}

选取右上角的代码如下

public class Solution {
    public boolean Find(int target, int [][] array) {
        int hang = array.length;
        int lie = array[0].length;
        for(int i=0,j = lie-1;i<hang&&j>=0;){
        	if(target == array[i][j]) return true;
            else if(target > array[i][j]) {i++;continue;}
            else {j--;continue;}
        }
        return false;
    }
}

    题目可以在牛客网练习,二维数组中的查找,这里假设了输入的数组不为空,实际还要做一些特殊输入判断。

    我第一个看到这个题自己的思路是,既然每一行是有序的,就可以逐行使用归并排序,最后得到一个有序的一维数组,再使用二分查找,不过显然时间复杂度和空间复杂度都比以上方法高。以上方法最差的时间复杂度是O(m+n)。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章