今日算法02二维数组中的查找

2023年 7月 14日 40.7k 0

一、题目描述

题目链接:leetcode.cn/problems/er…

难易程度:中等

在一个 n * m 的二维数组中,每一行都按照从左到右递增排序,每一列也按照从上到下递增排序。给定一个数,判断这个数是否在该二维数组中。

Consider the following 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]
]
​
Given target = 5, return true.
Given target = 20, return false.

二、解题思路

标志数法

若使用暴力法遍历矩阵 matrix ,则时间复杂度为 O(NM) 。暴力法未利用矩阵 “从上到下递增、从左到右递增” 的特点,显然不是最优解法。

我们发现:左下角元素 18 有一个特点,上面的数都比它小,右边的元素都比它大,符合这样规律的数字本题解中称为标志数。(右上角元素 15 也是标志数)

image-20230713211118551

matrix 中的 左下角元素 为标志数 flag ,则有:

  • 若 flag > target ,则 target 一定在 flag 所在 行的上方 ,即 flag 所在行可被消去。
  • 若 flag < target ,则 target 一定在 flag 所在 列的右方 ,即 flag 所在列可被消去。
  • 根据这个规律,得出算法流程:

  • 从矩阵 matrix 左下角元素(索引设为 (i, j) )开始遍历,并与目标值对比:

    • 当 matrixi > target 时,执行 i-- ,即消去第 i 行元素;
    • 当 matrixi < target 时,执行 j++ ,即消去第 j 列元素;
    • 当 matrixi = target 时,返回 true ,代表找到目标值。
  • 若行索引或列索引越界,则代表矩阵中无目标值,返回 false 。

  • 复杂度分析

    时间复杂度:O(M+N) ,其中,N 和 M 分别为矩阵行数和列数,此算法最多循环 M+N 次。

    空间复杂度:O(1) , i, j 指针使用常数大小额外空间。

    三、代码实现

    class Solution {
        public boolean findNumberIn2DArray(int[][] matrix, int target) {
            int i = matrix.length - 1, j = 0; // 左下角标志数
            while(i >= 0 && j  target) i--;
                else if(matrix[i][j] < target) j++;
                else return true;
            }
            return false;
        }
    }
    

    封面

    今日算法系列,题解更新地址:studeyang.tech/2023/0714.h…

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论