来源:牛客网 题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
public class Solution { private static final int CANNOT_FIND_FLAG=-1; /* 思路,先找出二维数组每一行第一个数字,与target比较, 如果比target大,那么就不参与比较,如果比target小,那么比较该行最后一个数字,如果比target小,那么不参与比较, 如果比target大,那么将这这行的序号记录在subArray中。 最终subArray中存储的这些行与target比较大小,使用二分法比较。 */ public boolean Find(int target, int [][] array) { //targetNum标记是否存在target值。 boolean targetNum=false; if(array.length>0){ //subArray,可能存在target的数组的所在行序号 int subArray[]=new int[array.length]; int subArrayIndex=0; //得到一系列可能存在target的行号,放入subArray中。 for(int i=0;i<array.length;i++){ if(array[i].length>0&&array[i][0]<=target){ if(array[i][(array[i].length-1)]>=target){ subArray[subArrayIndex]=i; subArrayIndex++; } } } //计算subArray中对应的每一行数据,看是否存在target。 for(int i=0;i<subArrayIndex;i++){ int arrayNum=subArray[i]; targetNum=findInArray(target,array[arrayNum]); //如果存在,直接返回true,不存在,继续查找。 if(targetNum==true)return true; } return targetNum; }else{ return false; } } /* 二分法比较每行数组与target大小,如果存在target一样大小的,返回true 如果不存在,返回false */ private boolean findInArray(int target,int [] array){ if(array.length<=0)return false; //二分法 if(array[array.length-1]!=target&&array[0]!=target){ int matchBegin=0; int matchEnd=array.length-1; int matchMid=0; while(matchBegin<=matchEnd){ matchMid=(matchBegin+matchEnd)/2; if(array[matchBegin]==target||array[matchEnd]==target){ return true; }else { if(matchMid==matchBegin||matchMid==matchEnd) return false; } if(array[matchMid]>target){ matchEnd=matchMid; }else if(array[matchMid]<target){ matchBegin=matchMid; }else{ return true; } } return false; }else{ return true; } } }以上是我的版本,但是不是最优的,因为题中给出的是“每一列都按照从上到下递增的顺序排序”,说明可以用更好的办法 如下:
class Solution { public: bool Find(vector<vector<int> > array,int target) { int m,n,x,y; m = array.size();//行数 n = array[0].size();//列数 x=m-1;y=0;//坐标定在左下角 while(x>=0 && y<=n-1){ if(target<array[x][y]){ x--;//遇小上移 } else if(target>array[x][y]){ y++;//遇大右移 } else { return true; } } return false; } }; 左下角开始,遇大右移,遇小上移,直到超过边界都没找到,得false。否则得true。