多一些Aha Time,发现技术的美妙🍺|

啊原来是这样呀

园龄:8年3个月粉丝:3关注:9

【剑指offer】38.二维数组中的查找

总目录:

算法之旅导航目录

 

1.问题描述

在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[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 }
View Code
复制代码

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 };
View Code
复制代码

 

本文作者:OhOfCourse

本文链接:https://www.cnblogs.com/OhOfCourse/p/16904781.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   啊原来是这样呀  阅读(12)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起