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

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

一、题目描述

题目链接:https://leetcode.cn/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/

难易程度:中等

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

1
2
3
4
5
6
7
8
9
10
11
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 ,则有:

  1. 若 flag > target ,则 target 一定在 flag 所在 行的上方 ,即 flag 所在行可被消去。
  2. 若 flag < target ,则 target 一定在 flag 所在 列的右方 ,即 flag 所在列可被消去。

根据这个规律,得出算法流程:

  1. 从矩阵 matrix 左下角元素(索引设为 (i, j) )开始遍历,并与目标值对比:
    • 当 matrix[i][j] > target 时,执行 i– ,即消去第 i 行元素;
    • 当 matrix[i][j] < target 时,执行 j++ ,即消去第 j 列元素;
    • 当 matrix[i][j] = target 时,返回 true ,代表找到目标值。
  2. 若行索引或列索引越界,则代表矩阵中无目标值,返回 false 。

复杂度分析

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

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

三、代码实现

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
int i = matrix.length - 1, j = 0; // 左下角标志数
while(i >= 0 && j < matrix[0].length)
{
if(matrix[i][j] > target) i--;
else if(matrix[i][j] < target) j++;
else return true;
}
return false;
}
}

封面

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

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

https://studeyang.tech/2023/0714.html

作者

Studeyang

发布于

2023-07-14

更新于

2023-07-13

许可协议

评论