劍指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)。


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