二維數組查找

題目

二維數組中的查找

在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。

例如:
1,2,5
3,4,9
7,8,21

3*3的數組

解答

思路

從二維數組的右上角的元素開始判斷,因爲此元素是它所在行的最大數,是它所在的列的最小數。如果它等於要查找的數字,則查找過程結束。如果它大於要查找的數字,則可以排除它所在的列。如果它小於要查找的數字,則可排除它所在的行。這樣如果要查找的數字不在數組的右上角,則每次判斷都可以排除一行或一列以縮小查找範圍,直到找到要查找的數字,或者查找範圍爲空。

代碼

Java代碼實現

    public boolean findNum(int [][] array,int target) {
        if(array == null || array.length==0 ||array[0].length==0){
            return false;
        }
        int rowLen = array.length; // 行數
        int columnLen = array[0].length; // 列數
        if(target < array[0][0] || target > array[rowLen-1][columnLen-1]){
            return false;
        }
        int i = 0;
        int j = columnLen-1;
        while(i<rowLen && j>=0){
            if(array[i][j] == target){
                return true;
            }else if(array[i][j] > target){
                j--;
            }else{
                i++;
            }
        }

        return false;
    }

擴展

若是在上題中加入一個條件:每行的首數大於上行的尾數
例如:
1,2,3
4,5,6
7,8,9

3*3的數組

思路

對於排好序的數組考慮使用二分查找法,可以得到O(logn)的查找效率。那麼這個二維數組其實可以看作一維有序數組,在這個一維數組中,元素被分爲m段,每段固定長度。即要將此二維數組映射到一個一維數組。
假設映射到一維數組A,A有m*n個元素,那麼A[k]=matrix[i][j], 當k=*n+j,即i=k/n, j=k%n。有了映射關係後就可以堆展開之後的一維數組進行二分查找,時間複雜度爲O(log(m*n))。

代碼

Java代碼實現

    public boolean findNumEx(int [][] array,int target) {
        if(array == null || array.length==0 || array[0].length==0){
            return false;
        }
        int rowLen = array.length;
        int columnLen = array[0].length;
        if(target < array[0][0] || target > array[rowLen-1][columnLen-1]){
            return false;
        }
        int low = 0;
        // 總共有rowLen*columnLen個元素
        int high = rowLen*columnLen-1;
        while(low <= high){
            int mid = (low + high)/2;
            if(array[mid/columnLen][mid%columnLen] == target){
                // 找到此元素,返回true
                return true;
            }else if(array[mid/columnLen][mid%columnLen] < target){
                // 在右半部分繼續找
                low = mid+1;
            }else{
                // 在右半部分繼續找
                high = mid-1;
            }
        }
        return false;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章