剑指Offer总结——二维数组的查找

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

这题思路很简单,我们先看一下题目:

重点就是每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。我们的思路可以是这样开始的:

  1. 直接从0到行末,从第一行到最后一行进行遍历
  2. 每次都拿出一个数字来和目标进行比较,如果找到了就返回true
  3. 当遍历到末尾后,还没有发现目标,那么就返回false

这样是可以的,但是当二维数组非常大的时候耗费的时间就会很大(时间复杂度大概在n^2,前提是二维数组近似方形且目标较靠后),不一定能够满足题目的要求,所以我们要根据上面画的重点来进行优化:

  1. 首先,可以确定的是行末,即最右边的数字,就是这一行最大的数字,因此,如果我们发现我们的目标比这个数字大就可以直接跳到下一行进行比对
  2. 如果最右边的数字比目标大,那么可以确定我们要找的目标只能是在左边或者下面,我们先考虑走到左边找目标数字的情况
  3. 当我们走到左边的时候,只会有两种情况,当前数字仍然比目标数字要大,以及比目标数字小,如果是比目标数字大,则我们继续向左走,最终情况会变回到后一种情况,即比目标数字小(如果都比目标数字大,那么可以确定已经没有可以比较的数字了,因为如果往下走,则可以发现下面的数字都比当前大,因为“每一列都按照从上到下递增的顺序排序”,而如果往上走,因为我们之前通过和上一行最大的数字比对,确定上一行的数字都比目标数字小,所以目标数字肯定不在上一行,因此可以直接结束掉循环,返回false
  4. 因为上一次比对的数字比目标数字小,因此我们直接向下走,不需要退回到下一行的行末,因为我们可以确定下一行的数字分别比上一行同一列的数字大,所以可以确定此时右侧的数字都比当前数字要大(因为目标数字比上一行的右侧的数字要小,而当前行右侧的数字又比上一行的同列的数字大),然后我们回到和情况2相似的步骤,发现比目标大则左移动,比目标小则向下移动……

总结一下,我们需要做的事情就是:

  1. 从最上面一行,最右侧开始比较,大了向左移动,小了向下移动
  2. 当遍历到比最左侧要左,比最下面一行要下(即超出边界)的时候,就断掉循环,返回false

原文地址:https://www.cnblogs.com/yejianying/p/jianzhioffer_2d_array_searching.html

时间: 2024-08-30 06:49:23

剑指Offer总结——二维数组的查找的相关文章

剑指offer:二维数组的查找

题目:在一个二维数组中,每一行都按照从左到右的递增顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样一个二维数组和一个整数,判断数组中是否含有该整数. 分析:数组如下所示 方式大致如下: 选择的应该是右上角或者左下角. // 二维数组matrix中,每一行都从左到右递增排序, // 每一列都从上到下递增排序 bool Find(int* matrix, int rows, int columns, int number) { bool found = false; if(ma

剑指offer(一) 二维数组的查找

题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 第一种方法,在每一行进行二分查找,NlogN. 第二种方法,也可能是最好的,因为已经是有序的,我们选取左下角或者右上角,每次进行判断大小,选择上移或者右移,这样每次都有贪心选择,但是这样的时间复杂度怎么确定呢? 特别注意边界的判断!否则空指针异常.获得传进来的数组和获得下标之间尤其要判断. class Solution

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

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 分析: 首先选择数组中右上角的数字.如果该数字等于要查找的数字,查找过程结束:如果该数字大于要查找的数字,剔除这个数字所在的列:如果该数字小于要查找的数字,剔除这个数字所在的行.依次类推,直到查找范围为空. 示例程序: #include <stdio.h> #include <stdlib.h> int

剑指OFFER之二维数组中的查找(九度OJ1384)

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数. 输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字. 接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每

剑指 Offer——1. 二维数组中的查找

题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 解法一 利用二位数组有序的特性,首先选取数组中右上角的数字.如果该数字等于要查找的数字,查找过程结束:如果该数字大于要查找的数字,剔除这个数字所在的列:如果该数字小于要查找的数字,剔除这个数字所在的行.也就是说如果要查找的数字不在数组的右上角,则每一次都在数组的查找范围中剔除一行或者一列,这样每

[剑指Offer]5.二维数组中的查找

题目 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路 [算法系列之三十三]杨氏矩阵 代码 /*--------------------------------------- * 日期:2015-07-19 * 作者:SJF0115 * 题目: 5.二维数组中的查找 * 网址:http://www.nowcoder.com/books/coding-interviews/a

《剑指Offer 1.二维数组中的查找》2019-03-25

剑指Offer  第一题 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 本人简单的解题思路  就是通过二重循环,遍历.查找数组中是否有目标数字,思路是简单的,但是有个小坑 ,就是没有进行数组越界判断 少判断了  array = [ [ ] ] 这种情况,最终通过的代码为 public class Solution { public bool

剑指offer(2) - 二维数组中的查找

题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上往下递增的顺序排序.请写一个函数,输入一个二维数组和一个整数,判断数组中是否含有该整数. 例如下面的二维数组就是每行.每列都是递增顺序,如果在这个数组中查找数字7,则返回true,如果查找数字5,由于数组中不含有该数字,则返回false. 1   2   8   9 2  4   9   12 4  7  10   13 6  8   11   15 public class FindFromMatrix { priv

剑指OFFER之二维数组中的查找

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数. 输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字. 接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每