1. 程式人生 > >順序二維陣列的查詢

順序二維陣列的查詢

1、題目

就是給定一個二維陣列,數組裡面從左到右,從上到下都是非降序。然後查詢某個值是否存在。這個題目在劍指offer裡面也有。不過這裡用的是自己想出來的方法。

2、解法

這裡涉及到快速查詢肯定是想著使用二分查詢。類比一維陣列的二分查詢,需要兩個指標表示範圍(也就是一條線段)。但是這裡是二維陣列,所以想著使用四個指標表示範圍(矩陣有四個角)。另外,二分查詢中肯定需要箇中點,這個中心點自然而然選擇矩形的中心點。在一維陣列,中心點把陣列分成了兩個部分。這裡在二維陣列中,可以看作中心點把矩形分成了四個小矩形。那麼如何進行二分查詢呢?

這裡如果中心點等於target,則很簡單。如果中心點對應的值小於target,那麼只能去除一個小矩形(如圖左上角)。這裡就發現沒法像二分查詢時候使用直接迭代的方法了。所以這裡使用遞迴呼叫,在剩下的三個小矩形中進行遞迴查詢。如果中心點對應的值大於target,同理分析即可。

另外有一個可以優化的地方。容易發現後面三個遞迴可以變成另個遞迴呼叫。因為下面的兩個小矩形可以組成一個大矩形(或者右側的兩個小矩形也可以組成一個大矩形)。


一步步思路,很自然。具體見程式碼。

class Solution {
public:
    bool fun(vector<vector<int>>& matrix, int target,int r1,int c1,int r2,int c2){
        int r_m,c_m;
        while(r1<=r2&&c1<=c2){
            r_m=r1+(r2-r1)/2;
            c_m=c1+(c2-c1)/2;
            if(matrix[r_m][c_m]==target){
                return true;
            }else if(matrix[r_m][c_m]>target){
                return fun(matrix,target,r1,c1,r2,c_m-1)||fun(matrix,target,r1,c_m,r_m-1,c2);
            }else{
                return fun(matrix,target,r_m+1,c1,r2,c2)||fun(matrix,target,r1,c_m+1,r_m,c2);
            }
        }
        return false;
    }
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int r1=0,c1=0,r2=matrix.size()-1,c2=matrix[0].size()-1;
        return fun(matrix,target,r1,c1,r2,c2);
    }
    
};