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

C++

判断数组是否为空

运用判断条件 matrix.size()==0 || matrix[0].size()==0 进行判断,判断时从左到右执行,如果 matrix 为空,不会引用到 matrix[0],所以就不会发生下标越界的情况。

实现

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        if(matrix.size()==0 || matrix[0].size()==0) return false;
        int m=matrix.size(); //行数
        int n=matrix[0].size(); //列数
        int i=0,j=n-1;
        while(j>=0 && i<m){
            if(matrix[i][j]>target) {
               j--; 
            }
            else if(matrix[i][j]<target){
                i++;
            } 
            else return true;
        }
        return false;
    }
};

Java

题目

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

分析

我在分析这个问题的时候,第一步首先想到的是,在纸上把代表二维数组的矩形画出来,然后分别查找第一行和第一列最先大于target值的行列坐标,这样可以把搜索范围确定在矩形的左上角。当然由于我没有给出测试用例,考虑的不周到,首先这样做在面对查找大数的时候跟全盘搜索没有区别,第一行第一列所有的数字都小于我要查找的target,相当于遍历全数组搜索。

笔记

下面对《剑指offer》书上对这个题的详解进行转述和记录:

当我们面对一个问题时,我们首先应该想到是化繁为简,具体问题具体分析。通过分析简单的例子,试图寻找普遍的规律。现在如果我们从数组的一个角上选取数字来和要查找的数字做比较,这样做会不会更简单呢?如下所示的测试用例,我们需要在其中查找数字7:

1    2    8       9
2    4    9      12
4    7    10    13
6    8    11    15

首先,我们选取数组右上角的数字9。由于9大于7,并且9还是第四列的第一个数字,也是该列当中最小的数字,因此7不可能出现在第四列。于是我们可以把第四列从搜索范围当中剔除,之后只需要考虑剩下的三列即可。在剩下的矩阵当中,右上角的数字为8,8位第三列的第一个数字。同上,我们可以把第三列从搜索范围当中剔除。

在剩下两列组成的数组当中,数字2位于数组的右上角。由于2是该数组第一行最后一个数字(也是最大的)数字,因此7不可能出现在数字2所在的行。于是我们可以把数字2所在的行剔除,只剩下三行两列的数字。在剩下的数组当中,4位于右上角,同上,我们把数字4所在的行也删除,最后剩下两行两列数字。

4    7 
6    8 

在剩下的数组当中,位于右上角的7刚好就是我们要查找的数字,于是查找过程结束。

同样,我们也可以选取左下角的数字。

1    2    8       9
2    4    9      12
4    7    10    13
6    8    11    15

数字6小于7,剔除6所在的列:

2    8       9
4    9      12
7    10    13
8    11    15

数字8大于7,剔除8所在的行:

2    8       9
4    9      12
7    10    13

查找到数字7,查找完成。

代码

public class Solution {
    public boolean Find(int target, int [][] array) {
        Boolean found=false;
        int rows=array.length;
        int columns=array[0].length;
        if(array.length!=0 && rows>0 && columns>0){
            int row=0;
            int column=columns-1;
            while(row<rows && column>=0){
                if(array[row][column]==target)
                {
                    found=true;
                    break;
                }
                else if(array[row][column]>target)
                    --column;
                else ++row;
            }
        }
        return found;
    }
}

测试用例

  1. 二维数组中包含查找的数字(查找的数字是数组中的最大值和最小值,查找的数字介于数组中的最大值和最小值之间)。
  2. 二维数组中没有查找的数字(查找的数字大于数组中的最大值,查找的数字小于数组中的最小值,查找的数字在数组的最大值和最小值之间但是数组中没有这个数字)。
  3. 特殊测试用例(输入空指针)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值