【剑指offer题解】二维数组中的查找

【剑指offer题解】二维数组中的查找

前言

众所周知,对于面试而言,《剑指offer》是一本“好书”。面试

若是你和我同样是个算法菜鸡,那么最推荐的是先把剑指offer的题目搞明白,其次再去刷LeetCode等习题,这样对于面试突击很是有用,由于面试官最常考的算法题都在这本书里。算法

若是你发现看这本书很吃力,能够先直接参考些网上的代码,照着抄一遍,理解下算法题是应该解题,多抄几道题目,你就对算法题的作法有感受了,这个高考作固定套路数学题是同样的。编程

对于剑指offer题解这个系列,个人写做思路是,对于看过文章的读者,可以作到:后端

  • 迅速了解该题常看法答思路(奇技淫巧不包括在内,节省你们时间,实在有研究需求的人能够查阅其它资料)
  • 思路尽可能贴近原书(例如书中提到的面试官常常会要求不改变原数组,或者有空间限制等,尽可能体如今代码中,保证读者能够不漏掉书中细节)
  • 尽可能精简话语,避免冗长解释
  • 给出代码可运行,注释齐全,关注细节问题
  • 代码可以经过牛客网在线编程《剑指offer》测试

《剑指offer题解》系列

你能够经过如下几种途径查看个人《剑指offer题解》系列:数组

  • 关注个人公众号:后端技术漫谈,点击公众号导航栏:剑指offer题解
  • 剑指offer题解专栏(CSDN)
  • 各大博客平台个人帐号(见本文最下方)

题目介绍

在一个二维数组中(每一个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。安全

解题思路

方法一

首先可以想到的确定是一行一行或者一列一列遍历,判断数组中是否含有该整数。该方法显然是最笨拙的二维数组遍历,面试官也不会满意,时间复杂度是O(n^2)微信

代码

Python

class Solution:
    def Find(self, target, array):
        for i in range(len(array)):
            for j in range(len(array[0])):
                if array[i][j]==target:
                    return True
        return False

方法二

咱们思考下,既然大的数字都在靠右边/下边,可否能利用行列的数据变化规律来优化下解法,若是寻找的目标数大于如今的数字,那么目标数字是在当前位置的右边或下边,若是所寻找的目标数小于如今的数字,那么目标数字在当前位置的左边或上边。举个例子,以下图数组所示:ide

1  2  3   4
2  3  8   9
3  4  9   10
4  5  10  11

咱们的位置是1,要找8,8大于1,那么在1的右边和下边区域进行下一步的搜索。函数

若是咱们先搜索他的右边,测试

2  3   4
3  8   9
4  9   10
5  10  11

又搜索了他们的下边,

2  3  8   9
3  4  9   10
4  5  10  11

这时候咱们发现

3  8  9
4  9  10
5  10 11

这个区域搜索了两次,咱们是从数组的第一个数[0][0]取的,遇到了重复搜索区域的问题。有没有方法去除重复的搜索区域呢,咱们发现,当从右上角取第一个数的时候,能够去除重复的搜索区域,仍是以这个数组为例,取4,搜索8,发现8比4大,那么8不可能出如今4这一行,只须要从下边搜索便可。若是寻找3,3比4小,4那一列后续的数都大于4,只须要从左边搜索便可。

1  2  3   4
2  3  8   9
3  4  9   10
4  5  10  11

咱们还能够发现左下角的点也能够去除重复搜索区域,总结起来的话,有点像变量控制法的感受,将一个变量控制住,根据另一个变量的规律,得出结论。

这样咱们将时间复杂度降为了O(n)

代码

Java

public class Solution {
    public boolean Find(int target, int [][] array) {
        int rows = array.length;
        int cols = array[0].length;
        int i = rows-1, j = 0;
        while(i >= 0 && j < cols){
            if(target < array[i][j])
                i--;
            else if(target > array[i][j])
                j++;
            else
                return true;
        }
        return false;
    }
}

Python

class Solution:
    def Find(self, target, array):
        if array == ([] or [[]]):
            return False
        row = len(array)
        col = len(array[0])
        i=0
        j=col-1
        while 0<=i<row and 0<=j<col:
            if target>array[i][j]:
                i=i+1
            elif target<array[i][j]:
                j=j-1
            else:
                return True
        return False

总结

题目简单,小伙伴们须要理解的是算法题应该注重的是效率优化,暴力穷举可以解决问题,但说服不了面试官。

个人《剑指offer题解》系列

你能够经过如下两种途径查看《剑指offer题解》系列:

  • 关注个人公众号:后端技术漫谈,点击公众号下方:剑指offer题解
  • 剑指offer题解专栏(CSDN导航页)
  • 各平台博客

关注我

我是一名后端开发工程师。

主要关注后端开发,数据安全,爬虫,物联网,边缘计算等方向,欢迎交流。

各大平台均可以找到我

  • 微信公众号:后端技术漫谈
  • Github:@qqxx6661
  • CSDN:@Rude3Knife
  • 知乎:@Zhendong
  • 简书:@蛮三刀把刀
  • 掘金:@蛮三刀把刀
  • 头条:@后端技术漫谈

原创博客主要内容

  • Java知识点复习全手册
  • Leetcode算法题解析
  • 剑指offer算法题解析
  • SpringBoot菜鸟入门实战系列
  • SpringCloud菜鸟入门实战系列
  • 爬虫相关技术文章
  • 后端开发相关技术文章
  • 逸闻趣事/好书分享/我的兴趣

我的公众号:后端技术漫谈

【剑指offer题解】二维数组中的查找
公众号:后端技术漫谈.jpg

若是文章对你有帮助,不妨收藏,投币,转发,在看起来~

相关文章
相关标签/搜索