美文网首页收藏
04. 二维数组中的查找

04. 二维数组中的查找

作者: 木木与呆呆 | 来源:发表于2022-03-07 14:12 被阅读0次

    链接

    https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/
    难度: #中等

    题目

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

    限制:

    0 <= n <= 1000
    0 <= m <= 1000
    

    注意:本题与主站 240 题相同:https://leetcode-cn.com/problems/search-a-2d-matrix-ii/

    代码框架

    class Solution {
        public boolean findNumberIn2DArray(int[][] matrix, int target) {
    
        }
    }
    

    题目解析

    每一行都按照从左到右递增的顺序排序,
    每一列都按照从上到下递增的顺序排序,
    可以分析得到,
    每一行的最左边是最小值,最右边是最大值,
    每一列的最上边是最小值,最下边是最大值,
    进一步分析,
    左上角的元素是最小值,
    右下角的元素是最大值,
    左下角的元素是第一列和最后一行的中间值,
    右上角的元素是第一行和最后一列的中间值。

    解答思路1:
    先循环二维数组的每一行,
    对每一行的有序数据进行二分查找,
    找到则返回true,
    找不到就二分查找下一行,
    如果全部都找不到,
    返回false。

    解答思路2:
    利用二维数组自身提供的有序性,
    进行二分思想的查找,
    最左下角的元素是第一列和最后一行的中间值,
    左下角的元素比当前列上面的值都大,
    也比当前行后面的值都小,
    使用i,j记录所在的元素,
    最先开始比较最左下角的元素,
    如果该元素比target大,则i--上移,
    如果该元素比target小,则j++右移,
    直到找到target,返回true。

    画图演示思路:


    测试用例

    package edu.yuwen.sowrd.num04.solution;
    
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    import edu.yuwen.sowrd.num04.sol2.Solution;
    
    public class SolutionTest {
        /**
         * 现有矩阵 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。
         */
        @Test
        public void testCase1() {
            Solution solution = new Solution();
            int[][] 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 } };
            int target = 5;
            boolean isFind = solution.findNumberIn2DArray(matrix, target);
            Assertions.assertTrue(isFind);
        }
    
        /**
         * 现有矩阵 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 = 20,返回 false。
         */
        @Test
        public void testCase2() {
            Solution solution = new Solution();
            int[][] 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 } };
            int target = 20;
            boolean isFind = solution.findNumberIn2DArray(matrix, target);
            Assertions.assertFalse(isFind);
        }
    
        /**
         * 现有矩阵 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 = 1,返回 true。
         */
        @Test
        public void testCase3() {
            Solution solution = new Solution();
            int[][] 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 } };
            int target = 1;
            boolean isFind = solution.findNumberIn2DArray(matrix, target);
            Assertions.assertTrue(isFind);
        }
    
        /**
         * 现有矩阵 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 = 30,返回 true。
         */
        @Test
        public void testCase4() {
            Solution solution = new Solution();
            int[][] 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 } };
            int target = 30;
            boolean isFind = solution.findNumberIn2DArray(matrix, target);
            Assertions.assertTrue(isFind);
        }
    
        /**
         * 现有矩阵 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 = 15,返回 true。
         */
        @Test
        public void testCase5() {
            Solution solution = new Solution();
            int[][] 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 } };
            int target = 15;
            boolean isFind = solution.findNumberIn2DArray(matrix, target);
            Assertions.assertTrue(isFind);
        }
    
        /**
         * 现有矩阵 matrix 如下:[
         * [1,2,3,4,5],
         * [6,7,8,9,10],
         * [11,12,13,14,15],
         * [16,17,18,19,20],
         * [21,22,23,24,25]]
         * 给定 target = 19,返回 true。
         */
        @Test
        public void testCase6() {
            Solution solution = new Solution();
            int[][] matrix = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 },
                    { 11, 12, 13, 14, 15 }, { 16, 17, 18, 19, 20 },
                    { 21, 22, 23, 24, 25 } };
            int target = 19;
            boolean isFind = solution.findNumberIn2DArray(matrix, target);
            Assertions.assertTrue(isFind);
        }
    
        /**
         * 现有矩阵 matrix 如下:[
         * [2,5],
         * [2,8],
         * [7,9],
         * [7,11],
         * [9,11]]
         * 给定 target = 7,返回 true。
         */
        @Test
        public void testCase7() {
            Solution solution = new Solution();
            int[][] matrix = { { 2, 5 }, { 2, 8 }, { 7, 9 }, { 7, 11 }, { 9, 11 } };
            int target = 7;
            boolean isFind = solution.findNumberIn2DArray(matrix, target);
            Assertions.assertTrue(isFind);
        }
    }
    

    解答1

    package edu.yuwen.sowrd.num04.sol1;
    
    public class Solution {
        public boolean findNumberIn2DArray(int[][] matrix, int target) {
            if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
                return false;
            }
    
            for (int i = 0; i < matrix.length; i++) {
                // 对每一行的有序数据进行二分查找
                boolean isFind = binarySearch(matrix[i], target);
                // 找到即可立即返回
                if (isFind) {
                    return true;
                }
            }
            // 全部都找不到
            return false;
        }
    
        /**
         * 二分查找数组中目标
         */
        private boolean binarySearch(int[] nums, int target) {
            int low = 0;
            int high = nums.length - 1;
            while (low <= high) {
                int mid = (low + high) / 2;
                if (target == nums[mid]) {
                    return true;
                }
                if (target < nums[mid]) {
                    high = mid - 1;
                }
                if (target > nums[mid]) {
                    low = mid + 1;
                }
            }
    
            return false;
        }
    }
    

    解答2 推荐

    package edu.yuwen.sowrd.num04.sol2;
    
    public class Solution {
        public boolean findNumberIn2DArray(int[][] matrix, int target) {
            if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
                return false;
            }
    
            // 计算矩阵的行数和列数
            int n = matrix.length;
            int m = matrix[0].length;
    
            // 最左下角,开始比较的元素位置
            int i = n - 1;
            int j = 0;
    
            while (i >= 0 && j < m) {
                int cur = matrix[i][j];
                if (cur == target) {
                    return true;
                }
    
                // 元素上移,朝着较小的数据移动
                if (cur > target) {
                    i--;
                }
    
                // 元素右移,朝着较大的数据移动
                if (cur < target) {
                    j++;
                }
            }
    
            return false;
        }
    }
    

    相关文章

      网友评论

        本文标题:04. 二维数组中的查找

        本文链接:https://www.haomeiwen.com/subject/tycnrrtx.html