Cracking the coding interview 9.6
Given a matrix in which each row and each column is sorted. write a method to find an element in it. 实现一个函数,在一个行列都排序的二维数组中查找某个元素是否存在。
思路:如果待搜索元素小于一行中最左边的元素或者大于一行中最右面的元素,那么待查找元素不可能存在于当前行中。列也同理。从上下左右四个方向,从外向内分别判断待查找元素是否可能存在于其中。逐步缩小搜索范围。
/**
* Search specific value in sorted 2D array, which both row and column are sorted in ascending order.
*
* arr: address of a array, row-major order stored
* nRow: row of input array
* nColumn: column of input array
* nVal: the value that to be searched
*/
bool SearchSorted2D(int *arr, const int nRow, const int nColumn, const int nVal)
{
int nTop = 0;
int nBottom = nRow - 1;
int nLeft = 0;
int nRight = nColumn - 1;
while ((nTop <= nBottom) && (nLeft <= nRight))
{
// Compare with the most top-left(smallest) and the most bottom-right(biggest) element.
if (nVal < (*(arr+nColumn*nTop+nLeft)) || (nVal > (*(arr+nColumn*nBottom+nRight))))
return false;
if (*(arr+nColumn*nTop+nRight) == nVal)
{
printf("arr[%d][%d]=%d\n", nTop, nRight, *(arr+nColumn*nTop+nRight));
return true;
}
if (*(arr+nColumn*nBottom+nLeft) == nVal)
{
printf("arr[%d][%d]=%d\n", nBottom, nLeft, *(arr+nColumn*nBottom+nLeft));
return true;
}
if ((nTop == nBottom) && (nLeft == nRight))
return false;
//
// Search from top-right corner
// the most right element of row is smaller than nVal, then the whole row is smaller than nVal
if (*(arr+nColumn*nTop+nRight) < nVal)
nTop ++;
// the most top element of column is bigger than nVal, then the whole column is smaller than nVal
if (*(arr+nColumn*nTop+nRight) > nVal)
nRight --;
//
// Search from bottom-left corner
// the most bottom element of column is smaller than nVal, then the whole column is smaller than nVal
if (*(arr+nColumn*nBottom+nLeft) < nVal)
nLeft ++;
// the most left element of row is smaller than nVal, then the whole row is smaller than nVal
if (*(arr+nColumn*nBottom+nLeft) > nVal)
nBottom --;
}
return false;
}