二维数组中的查找(中等)|Java刷题打卡

450 阅读2分钟

 本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接

题目描述

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

[

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

]

给定 target = 7,返回 true。

给定 target = 3,返回 false。

示例1

输入: 7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]

返回值: true

**说明:**存在7,返回true

示例2

**输入:**3,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]**

**返回值:**false

说明: 不存在3,返回false

题目分析

暴力法

遍历一遍整个数组,判断有没有该整数即可,时间复杂度O(n2),这种做法只是不得已而为之,这里就不写了

从左下角找

因为数组从左往右和从上到下都是有序的,我们就可以从数组的左下角或右上角开始找,比如从左下角开始,如果这个元素比target小,那么就在这一行向右找,因为右边的元素比当前元素大;如果这个元素比target大,那么就从这一列向上找,因为上边的元素比下边小

即对于左下角的值 m,m 是该行最小的数,是该列最大的数,每次将 m 和目标值 target 比较:

  • 当 m < target,由于 m 已经是该行最大的元素,想要更大只有从列考虑,取值右移一位

  • 当 m > target,由于 m 已经是该列最小的元素,想要更小只有从行考虑,取值上移一位

  • 当 m = target,找到该值,返回 true

    public boolean Find(int target, int[][] array) { // 选取左下角这个元素array[row][col] int row = array.length - 1; int col = 0;

        while (true) {
            // 如果比target大,那么就向上找
            if (row > -1 && col < array[0].length && array[row][col] > target) {
                row--;
            }
    
            // 如果比target小就向右找
            if (row > -1 && col < array[0].length && array[row][col] < target) {
                col++;
            }
            // 越界了都没找到target说明不存在
            if (row == -1 || col == array[0].length) {
                return false;
            }
    
            if (array[row][col] == target) {
                return true;
            }
        }
    }
    

    }

总结

这种方法最多是从左下角遍历到右上角,时间复杂度为O(2m),m就是数组的长度

对于这种有序的数组,一般想到的就是二分法,其实这种解法也算是二分法了。左下角的数是该行最小的数,是该列最大的数。这个解法是从坐下角,也可以从右上角开始判断,其实是一样的。