剑指Offer04:二维数组中的查找(解决matrix[0].length数组越界异常)

剑指Offer04:二维数组中的查找(解决matrix[0].length数组越界异常)

1、题目描述

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

示例:

现有矩阵 matrix 如下:

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。

给定 target = 20,返回 false。

2、解题思路

(1)题目说了要高效的搜索方法,所以排除暴力循环。
(2)数组是从左到右从上往下递增的,所以每一行同列的数都比前一行大,每一行第一个数是当前行最小的。
(3)这里选择的方法是从左下角开始找,因为如果target比对比的数小,那就直接排除当前行,j--;如果比当前数大,直接j++排除前一列。
 (4)也就是一次排除一行或者一列,效率较高。

tips:数组越界异常
在写代码的时候我发现:
int row = matrix[0].length;//会出现数组越界异常
就算是数组判空之后还是会出错,于是搜索了下,发现java里面即使数组不为空,但长度也可能为0,此时就会报错。具体的在代码里详细做了笔记。

String[] s0={}; 此时s0不为空,但长度为0,开辟了内存,但内存中没有放任何东西,所以其长度为0,但不为空(已经开辟内存了)

3、代码

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
//java中数组为空和数组长度为0的区别
// String[] s0={};
// String[] s1={null,null};
// Strign s2=new String[2];
// String[] s3=null;

// 此时s0不为空,但长度为0,开辟了内存,但内存中没有放任何东西,所以其长度为0,但不为空(已经开辟内存了)
// s1不为空,长度为2,开辟内存的同时,将两个null放入内存中,所以长度为3.
// s2不为空,长度为2,虽然没有初始化但s2[0],s2[1]有默认值null,和s1类似.
// s3为空,没有长度,调用s3.length会空指针异常,虚拟机不会为其开辟内存,s3不指向任何地方
// 注:一旦等号右边有大括号产生,或者长度已经定,在内存中都会为其开辟内存,而数组的长度则取决于开辟的内存中放入东西的个数,数组为空时,不存在长度这一说,但当长度为0是数组却不一定为空
        //if (matrix.length==0) return false;
        //行数=数组名.length,列数=数组名[0].length
        int col = matrix.length;
        //int row = matrix[0].length;//这样写在数组长度为0时会报错,所以要先判数组长度是否为0
        int i=col-1,j=0;
        //先判断i>=0就相当于判断了数组是不是空数组,防止后面matrix[0].length越界报错,或者是在第一句的时候判断数组是否为0
        while(i>=0 && j<matrix[0].length){
            //从数组左下角开始找,如果大于左下角的就列数加1,去掉前一列,小于就行数减一,去掉后一行
            //不能从右下角开始找,不好排除,应该从本行最小又比上面同一列的都大的开始找
            if (target==matrix[i][j]) return true;
            else if(target<matrix[i][j]) i--;
            else if(target>matrix[i][j]) j++;
        }
        return false;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值