面试题04-二维数组的查找

题目:在一个 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。

题目分析:

思路一: 首先想到的是通过遍历整个数组,看是否存在这样一个与目标值相等的元素,如果有返回true, 如果没有返回false。

思路二:思路一是暴力的方法,时间复杂度为 O ( n 2 ) O({n^2}) O(n2),没有充分利用从左到右从上到下递增 这一条件。

第一步: 根据观察,我们需要先从数组的右上角出发,如果目标值比当前元素大,目标值如果存在的话,一定在当前元素的左边。如果目标值比当前元素小,目标值如果存在的话,一定在当前元素的下边。每次移动位置可以过滤一行或者一列。如此循环即可。
(从数组的左下角出发也是可以的)

第二步:循环条件。通过下移后,发现行数索引值已经超过数组本身行数,或者通过左移,发现列数索引值小于0。

Java代码:
import java.util.Arrays;
public class Offer04 {
    public static void main(String[] args) {
        int[][] array = {
                {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},
                {19, 22, 24, 27, 33},
                {23, 29, 35, 36, 39}
        };
        System.out.println(f(array,29));
        System.out.println(Arrays.toString(g(array,29)));
    }
    private static boolean f(int[][] array, int target) {
        // 要先判断二维数组的有效性,这一步很重要
        if (array == null || array.length == 0 || array[0].length == 0) {
            return false;
        }
        int row = array.length;    // 获取二维数组的行数
        int col = array[0].length; // 获取二维数组的列数
        // 从二维数组的右上角开始位置搜索。 array[0][col-1]
        int i = 0;
        int j = col-1;
        // 使用while更好。
        while (i<row && j>=0){
            if(target<array[i][j]){
                j--;
            }else if(target>array[i][j]) {
                i++;
            }else {
                return true;
            }
        }
        return false;
    }
	// 该函数是我自用于得到目标值所在下标添加的。。
    private static int[] g(int[][] array, int target) {
        // 要先判断二维数组的有效性,这一步很重要
        if (array == null || array.length == 0 || array[0].length == 0) {
            return (new int[]{-1,-1});
        }
        int row = array.length;    // 获取二维数组的行数
        int col = array[0].length; // 获取二维数组的列数
        // 从二维数组的右上角开始位置搜索。 array[0][col-1]
        int i = 0;
        int j = col-1;

        //不能使用for循环,使用while更好。
        while (i<row && j>=0){
            if(target<array[i][j]){
                j--;
            }else if(target>array[i][j]) {
                i++;
            }else {
                return (new int[]{i,j});
            }
        }
        return (new int[]{-1,-1});
    }
}

【注】
(1):leetcode 等平台只要我们完成一个函数即可,本人初出茅庐,为了巩固基本知识,故自己补充了部分代码,用于练手。
(2):一定要注意先判断数组是否为空,我自己搞了半个小时,最后发现因为没有对数组有效性进行判断这样的低级错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值