《剑指Offer》面试题3:二维数组中的查找

Posted littlecurl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指Offer》面试题3:二维数组中的查找相关的知识,希望对你有一定的参考价值。

《剑指Offer——名企面试官精讲典型编程题》

作者:何海涛


一、书上原题再现

面试题3:二维数组中的查找

题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。

请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。


二、涉及的知识点

 技术分享图片                      

 


三、解题过程

  首先一看到数组,就会下意识的想到遍历,就是挨个比较,看看要查找的数在不在里面,遍历虽然是万能的,但是一个一个的比较,未免太过麻烦。不妨找找有没有其他的方法,如果实在是找不到,最后再用遍历的方法。

  这道题比较特殊,特殊在数字是有序的,最小的数在左上角,最大的数在右下角,如下图所示:

 技术分享图片

  假如要查找9是否在二维数组内,我们可以选择从右上角开始查找,发现9>4,因为从左到右递增,9都比4这一行最右边的一个数大了,所以这时候就可以忽略4左边的所有数了,直接往下走进行比较(相当于删掉一整行),发现9>8,同理,继续往下(相当于删掉一整行),发现9<12,说明9有可能在12的左边,往左走进行比较,发现9<11,同理,继续往左,发现9<10,继续往左,发现9=9,返回结果为true,说明9在该二维数组中。

  如下图所示:

 技术分享图片

  对上面这段话的一开始有个疑问,为什么要从右上角开始进行比较,能不能换个地方?

  答案是:能。

  发现右上角往左是递减,往下是递增。

  相似左下角往右是递增,往上是递减。

  所以左下角也可以当做入手点,能够实现比较一个数就删掉一整行。

  还有左上角和右下角,这两个不能当做入手点,以左上角为例,最初数字1位于数组的左上角,因为这个数组是往右和往下两个方向递增的,我们要查找9,那么就无法做到删掉一行,因为9既有可能在1的右边,也有可能在1的下边,右下角道理相似。


四、调试步骤

  使用MyEclipse进行调试

 技术分享图片

  上图为示意图的代码实现:

一、 先把flag设为false,默认不存在。

二、 默认数组每行的列数都相等,所以可以

   用rows=array.length来代表行数,

   用columns=array[0].length来代表列数。

三、 row 和 column 来控制比较的切入点为右上角,

   所以row=0,column=columns-1,减一是因为数组下标索引从0开始而不是从1开始。

 

  我的完整测试代码:

  https://github.com/littlecurl/CodingInterviews

 

 


五、总结

  因为这道题的特殊性,所以有特殊解法的存在。与遍历的方法相比,这样一次删掉一行或一列的方法显然要快速的多。

 


六、声明与致谢

本题源代码请移步《剑指Offer》作者何海涛的GitHub:https://github.com/zhedahht/CodingInterviewChinese2

      

参考文章:(每篇文章我都会去点赞技术分享图片,好的文章就应该公诸于世,大家共同学习)

  GitHub博客:

       Littlecurl的《二维数组中的查找》:

https://littlecurl.github.io/littlecurl.github.io/%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E6%9F%A5%E6%89%BE-%E5%89%91%E6%8C%87Offer/

 

以上是关于《剑指Offer》面试题3:二维数组中的查找的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer(纪念版) 面试题3:二维数组中的查找

[ 剑指offer ] 面试题4:二维数组中的查找

剑指offer面试题 4.二维数组中的查找

剑指Offer面试题九度OJ1384:二维数组中的查找

剑指Offer学习面试题:二维数组中的查找PHP实现

剑指offer 面试题04. 二维数组中的查找