【剑指offer】38.二维数组中的查找
总目录:
1.问题描述
在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
 [1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
 
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
  ] 
给定 target = 7,返回 true。
   给定 target = 3,返回 false。
     数据范围:矩阵的长宽满足 0≤n,m≤500, 矩阵中的值满足 0≤val≤10^9
 进阶:空间复杂度 O(1),时间复杂度 O(n+m) 
2.问题分析
1遍历,利用好从上到下递增、从左到右递增,该放弃某行时就迅速放弃某行。从右上角或左下角开始,因为这里的值左边的都小于它,下面的都大于它,有点像二叉搜索树。
2二分搜索,因为行和列都是有序的,非常适合二分搜索。二分找到适合启动搜索的行/列,再在列/行内进行二分搜索。
3.代码实例
1遍历
 
1 public class Solution { 2 public boolean Find(int target, int [][] array) { 3 /* 4 思路:从左下角(或者右上角)开始查找,因为该行右边大于它,上边小于它,每次比较可以删除某一行或者某一列 5 注意:左上和右下不可以,因为无法减小问题规模(行和列都无法删除) 6 */ 7 if(array==null) 8 return false; 9 int row=array.length; //行数 10 int col=array[0].length; //列数 11 for(int i=row-1,j=0;i>=0&&j<col;){ //从左下角开始查找 12 if(array[i][j]==target) //找到 13 return true; 14 else if(array[i][j]>target) //不可能在该行,跳过该行 15 i--; 16 else //不可能在该列,跳过该列 17 j++; 18 } 19 return false; 20 } 21 }
2二分搜索
 
1 class Solution { 2 public: 3 bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) { 4 int rows=matrix.size(); 5 if(rows==0) return false; 6 int cols=matrix[0].size(); 7 if(cols==0) return false; 8 if(matrix[0][0]>target||matrix[rows-1][cols-1]<target) return false; 9 10 int mid=0; 11 int left=0,right=cols-1; 12 while(left<=right){ 13 mid=left+(right-left)/2; 14 if(matrix[0][mid]<target){ 15 left=mid+1; 16 continue; 17 } 18 if(matrix[0][mid]>target){ 19 right=mid-1; 20 continue; 21 } 22 //正好遇到 23 return true; 24 } 25 //left-1是最后一个可用列 26 27 for(int i=left-1;i>=0;i--){ 28 //剪枝操作 29 if(matrix[rows-1][i]<target) return false; 30 31 int top=0,bottom=rows-1; 32 while(top<=bottom){ 33 mid=top+(bottom-top)/2; 34 if(matrix[mid][i]<target){ 35 top=mid+1; 36 continue; 37 } 38 if(matrix[mid][i]>target){ 39 bottom=mid-1; 40 continue; 41 } 42 return true; 43 } 44 } 45 46 return false; 47 } 48 };
 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号