Monday, August 7th

 Searching a matrix

Given an mxn matrix, where each row is sorted and the first entry in a row is greater than the last entry in the previous row, determine whether or not a target value exists in the matrix.  The answer should be in O(log(m*n)) time


Went a little overkill today.  Approached the problem with double binary search, first finding the row that the target value may exist, then perform binary search on the row to determine whether or not the value exists

Initialize some variables

    int numrows=matrix.size();
int numcols=matrix[0].size();

int cstart=0, cend=numcols;
int rstart=0, rend=numrows;

int rmid, cmid=(cend+cstart)/2;

Perform binary search on the rows to determine which row, rmid, may contain the target value

    while(rstart < rend) {
rmid=rstart+(rend-rstart)/2;
if(matrix[rmid][cmid]==target) {
return true;
} else if(matrix[rmid][cmid]<target) {
rstart=rmid+1;
} else {
rend=rmid;
}
}

Now it's possible that the target value could still exist on a row directly above or below the outputted row rmid.  So, depending on whether the target value is less than or greater than middle column of the row, we compare the corresponding edge value to the target value.  If it's found the target value may exist on a separate row, we update rmid appropriately

    if(matrix[rmid][cmid]<target && matrix[rmid][numcols-1]<target && rmid < numrows-1) {
rmid++;
} else if( matrix[rmid][cmid]>target && matrix[rmid][0]>target && rmid > 0) {
rmid--;
}

Once we have the correct row, it's again vanilla binary search to find whether or not the target vale exists

    while(cstart < cend) {
cmid=cstart+(cend-cstart)/2;
if(matrix[rmid][cmid]==target) {
return true;
} else if(matrix[rmid][cmid]<target) {
cstart=cmid+1;
} else {
cend=cmid;
}
} 

Of course, if nothing hits, then we return false

return false;

It's possible to solve this problem by running binary search only once.  This is accomplished by treating the matrix as one long array, and converting matrix indices to the index of the corresponding array.  Still, my double binary search solution still ran in 0ms.

Working out the binary search muscles.  Still learning the algorithm's edges

Full code below:

    bool searchMatrix(vector<vector<int>>& matrix, int target) {
int numrows=matrix.size();
int numcols=matrix[0].size();

int cstart=0, cend=numcols;
int rstart=0, rend=numrows;

int rmid, cmid=(cend+cstart)/2;
while(rstart < rend) {
rmid=rstart+(rend-rstart)/2;
if(matrix[rmid][cmid]==target) {
return true;
} else if(matrix[rmid][cmid]<target) {
rstart=rmid+1;
} else {
rend=rmid;
}
}
if(matrix[rmid][cmid]<target && matrix[rmid][numcols-1]<target && rmid < numrows-1) {
rmid++;
} else if( matrix[rmid][cmid]>target && matrix[rmid][0]>target && rmid > 0) {
rmid--;
}

while(cstart < cend) {
cmid=cstart+(cend-cstart)/2;
if(matrix[rmid][cmid]==target) {
return true;
} else if(matrix[rmid][cmid]<target) {
cstart=cmid+1;
} else {
cend=cmid;
}
}

return false;
}

Comments

Popular posts from this blog

Wednesday, September 20th

Monday, September 11th

Tuesday, September 19th