74、240 搜索有序的二维矩阵

74   搜索整体有序的二维数组                                                                                                                       点击此处返回总目录

240 搜索行有序、列有序的二维数组

 

 

 

 

一、搜索整体有序的二维数组

 

【题目】

 

【方法一】

整个数组是从小到大排列的,可以看成是一行的有序数组,对有序数组进行查找可以通过二分查找法完成。

 

 

代码:

 

结果:

 

时间复杂度:log(m*n)

 

【方法二】

首先看第一列,找到第一个比target小的元素。则这个元素所在的行就是可能出现target的行。然后在这一行使用二分查找。

 

 

 

代码:

 

结果:

 

时间复杂度:m+log(n)

第二种方法的时间要慢一点。

 

【方法三】

方法二中找第一个比target小的元素使用的是顺序查找的方法,其实我们也可以使用二分查找来做。这样就有了方法三。

首先二分查找第一列,找到第一个比target小的元素。然后再这个元素所在的行再进行二分查找。

这就有点想分块查找的意思了。块内有序,块间有序。

 

怎么通过二分查找法查找第一个小于等于target的元素,见我的另一篇博客:《二分查找法及延伸》

 

 

代码:

 

结果:

 

时间复杂度:log(m)+log(n)

 

【方法四】

比如数组:

[[1 ,  3,   5,  7],

 [10,11,16,20],

 [23,30,34,50],

 [56,60,66,70]]

 

首先看第一行最后一个元素7,如果7比target小,说明第一行的所有元素都比target小,就可以排除第一行。如果7比target大,说明最后一列所有元素都比target大,就可以排除最后一列。

 

 

代码:

 

结果:

时间复杂度:m+n

 

 

【总结】 

这四种方法的时间复杂度分别为 log(m*n) 、m+log(n)、log(m)+log(n)、m+n

因为log(m*n) = log(m)+log(n)。所以方法1,3一样好。都是log这个级别。由于代码1简洁一些,所以排在第一吧。

方法2,4都是线性级别。2要好于4。

 

因此四种方法排名为:

1 >= 3 > 2 > 4

 

方法4只利用了行递增、列递增的信息,没有用到整体有序这个信息,所以最慢也正常。但是这种方法也挺巧妙的,还是要会。

 

 

二、搜索行有序、列有序的二维数组

 

【题目】

 

比上一个题目条件放宽了,不再要求整体有序。只要求每一行递增,每一列递增。

那怎么办呢?

上题的方法一,显然不能用,因为整体无序。

方法二三,也不能用,因为一个数可能出现在好几行的位置。

方法四可以用。

 

 

【方法一】

即上题的方法四。

比如数组:

[[1, 3,   5,  7],

 [4,11,16,20],

 [8,12,18,40],

 [9,17,32,60]]

 

首先看第一行最后一个元素7,如果7比target小,说明第一行的所有元素都比target小,就可以排除第一行。

                                                       

 

如果7比target大,说明最后一列所有元素都比target大,就可以排除最后一列。

                                                        

 

代码:

 

结果:

 

 

【方法二】

使用二分查找的思想,但是比较麻烦。每次排除1/4的内容。

每次考虑矩阵最中间的元素。

如果这个元素比target小,说明左上角的四分之一(红色框框)都不需要找了,只需要考虑右上角、右下角和左下角的(蓝色框框)即可。

                                                          

如果这个元素比target大,说明右下角的四分之一(红色框框)都不需要找了,只需要考虑左上角、右上角和左下角的(蓝色框框)即可。

                                                           

 

 

代码:

 

结果:

 

 

效果不太理想。

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值