在矩阵中找目标值(搜索二维矩阵)

给一个mxn的二维矩阵,行和列上的元素都按值严格递增,没有重复,给定一个目标值,搜索此矩阵找此值,如果找到了返回值在矩阵中的位置,否则返回-1,-1。

搜索的方法是先在矩阵对角线上搜索,如果小于左上角第一个元素,则说明矩阵中不存在目标值。如果值等于对角线上的某一元素,则直接返回。如果目标值介于对角线上某两个元素之间,则以这两个元素中大于目标值的元素为基准把矩阵分割成四部分,那么目标值有可能就在此基准元素的右上和左下矩阵中,因此递归地在这两个矩阵中寻找。如果值大于所有对角上的元素,若矩阵是方阵,则说明目标值不存在;若矩阵的行大于列,则目标值有可能在以对角线最大值为基准的下面的矩阵中,递归寻找;若矩阵的列大于行,则目标值有可能在对角线最大为基准的右边的矩阵中,递归寻找。

代码如下:

#include<iostream>
#include<vector>
#include<map>

using namespace std;

bool searchTarget(const vector<vector<int>>& data,int bR,int bC,int eR,int eC,int target,pair<int,int>& result)
{
    int i=bR,j=bC;
    for(;i<eR&&j<eC;i++,j++)
       {//check the element on the diagonal
               if(data[i][j]==target){
                    result=pair<int,int>(i,j);
                    return true;
                }else if(target<data[i][j]){
                    if(i>bR&&j>bC&&i<eR&&j<eC){    //target is between two valid p[i][j]
                         if(searchTarget(data,bR,j,i,eC,target,result)){// search on upper right
                              return true;
                          }
                         if(searchTarget(data,i,bC,eR,j,target,result)){   //search on lower left
                              return true;
                          }
                     }else{// target is less than all elements on the diagonal
                         return false;
                     }
                }
            
       }
    //target is greater than elements on the diagonal
     if(i>=eR&&j<eC){//the column is greater than the row
         if(searchTarget(data,bR,j,eR,eC,target,result)){// search on right
                  return true;
           }
     }else if(i<eR&&j>=eC){  //the column is less than the row
          if(searchTarget(data,i,bC,eR,eC,target,result)){// search on lower
                  return true;
           }
     }
     return false;    //the matrix is square  i>=eR&&j>=eC
}

int main()
{
   vector<vector<int>> data={{1,2,3,5,6},
                             {4,7,8,11,13},
                             {9,10,14,17,20},
                             {15,18,19,25,30}};
   int target=15;
   pair<int,int>result(-1,-1);
   searchTarget(data,0,0,data.size(),data[0].size(),target,result);
   cout<<result.first<<" "<<result.second<<endl;  //if not exist ,out -1 -1
   return 0;
}

到这里还没结束,如果题目中增加一个条件:每行的第一个整数大于前一行的最后一个整数。那么这个题目就可以有另一种特别简洁的做法,主要用到了二分搜索的方法。详情见https://blog.csdn.net/Jeff_Winger/article/details/81366596

猜你喜欢

转载自blog.csdn.net/Jeff_Winger/article/details/81366357
今日推荐