题目大意:
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
解题思路一:时间复杂度O(m*n)
这是最简单的一种方法,直接逐个遍历每一个矩阵中的元素,如果在遍历过程中匹配到了目标元素就返回true,否则遍历结束后返回false.这种方法虽然简单,但是时间复杂度高,效率太低,会超时。而且这种方法没有利用到矩阵元素中每行升序递增,每列升序递增的性质。
class Solution {
public:
bool searchMatrix(vector >& matrix, int target)
{
int col;
if(matrix.size()==0)
return false;
else
col=matrix[0].size();
for(int i =0;i
注意到数组中每一行和每一列都分别按照升序排列。 我们把矩阵以排在中心的那个元素为分界点,划分出四个区域,如图所示。 如果红点位置(即处于中间位置的元素)比目标元素小,那么意味着区域I中的所有元素都会比目标元素要小,接下来只需要对II,III,V三个区域进行搜索就可以了。如果红点位置的元素比目标元素大,则V区域中所有的元素都比目标元素大,只要搜索I,II,III这三个区域就可以了。而且剩下的三个区域行和列的规模都是原来矩阵的二分之一。我们以每个要搜索的区域的左上顶点和右下顶点作为边界区域,当左上顶点的行或列的大小超过了右下顶点的对应坐标,那么搜索就结束了。
接下来对剩余的三个区域递归地使用同样的方法进行搜索和排除,则T(n)=3T(n/2)+O(1)
根据Master theorem,可以计算出这种方法的时间复杂度为O(n^(log (2)3),大约为O(n^1.58),大大提高了算法的效率。
bool search(vector >& matrix,int row0,int col0,int row1,int col1,int target)
{
if(row0>row1||col0>col1||row0<0||col0<0||row1>matrix.size()-1||col1>matrix[0].size()-1)
return false;
int x=(row0+row1)/2;
int y=(col0+col1)/2;
if(x>row1||y>col1||xtarget)
{
return (search(matrix,row0,col0,x-1,y-1,target)||search(matrix,row0,y,x-1,col1,target)||search(matrix,x,col0,row1,y-1,target));
}
else
{
return (search(matrix,x+1,y+1,row1,col1,target)||search(matrix,row0,y+1,x,col1,target)||search(matrix,x+1,col0,row1,y,target));
}
}
bool searchMatrix(vector >& matrix, int target)
{
if(matrix.size()==0||matrix[0].size()==0)
return false;
else
return search(matrix,0,0,matrix.size()-1,matrix[0].size()-1,target);
}
不过在用这种方法的时候要注意不要再把已经判断过的中间元素再划入新的搜索区域中,也要小心不要把该元素所在的行或者列遗漏掉,各个区域也不应该有重合的部分。