#LC74. 搜索二维矩阵
搜索二维矩阵
你好!作为教练,我很高兴能带你剖析这道经典的“矩阵搜索”问题。在 NOI 竞赛中,这属于基础算法应用范畴,考察的是你对单调性的敏锐观察力以及坐标映射的熟练度。
一、 题目描述 (NOI 竞赛格式)
题目名称:搜索二维矩阵 (Search a 2D Matrix)
文件输入:matrix.in
文件输出:matrix.out
时间限制:1.0s
内存限制:256MB
【问题描述】
给你一个 的整数矩阵 matrix ,它具有以下两个特点:
- 每行中的整数从左到右按非严格递增顺序排列。
- 每行的第一个整数大于前一行的最后一个整数。
给定一个目标值 target ,如果 target 在矩阵中,输出 true;否则,输出 false 。
【输入格式】 第一行包含两个整数 和 ,表示矩阵的行数和列数。 接下来 行,每行包含 个整数,表示矩阵的内容。 最后一行包含一个整数 。
【输出格式】
输出一行,包含字符串 true 或 false。
【样例 1 输入】
3 4
1 3 5 7
10 11 16 20
23 30 34 60
3
【样例 1 输出】
true
【数据范围】
二、 预备知识点
- 二分查找 (Binary Search):这是处理有序序列搜索的最快工具。
- 坐标转换/映射:在 1D 线性索引与 2D 矩阵坐标(行、列)之间建立数学对应关系。
- 单调性分析:识别题目给出的两个特点共同构成的“全局递增”性质。
三、 启发式思维引导
现在,请拿出你的草稿纸,跟着我的引导一步步推导:
第一步:观察矩阵的逻辑结构 在草稿纸上画出一个 的矩阵,填入递增数字。 问:按照题目的描述,如果我把第一行写完,接着写第二行,再写第三行……这一长串数字是什么规律? 答:你会发现它们排成了一个完全有序的升序数组。
第二步:抽象化处理 由于整个矩阵在逻辑上是一个有序数组,我们是否可以不把它看作矩阵,而看作一个长度为 的一维数组? 问:在这个长度为 的一维数组中查找一个数,最优的时间复杂度是多少? 答:。
第三步:解决“索引转换”难题
假设一维数组的下标是 mid(范围 到 ),如何找到它在二维矩阵中对应的 matrix[row][col]?
请在草稿纸上列出 的情况:
- 推导公式:
row = mid / n(利用整除获取行号)col = mid % n(利用取模获取列号)
四、 算法复杂度分析思考
-
时间复杂度:
- 我们在 个元素中进行二分。
- 每次判定只需要 的坐标转换。
- 总复杂度:。
- 优化建议:对于本题 的规模,这个复杂度远超要求(实际上 级别都能轻松应对)。
-
空间复杂度:
- 我们只需要存储 等常数个变量。
- 复杂度:。
五、 算法流程图 (Mermaid 语法)
以下是基于 C++14 标准逻辑实现的算法流程。注意图中避免了特殊符号导致的解析问题。
graph TD
A(开始) --> B(获取矩阵行数m和列数n)
B --> C(设置左边界 left 等于 0)
C --> D(设置右边界 right 等于 m 乘 n 减 1)
D --> E{left 小于等于 right}
E -- 否 --> F(输出 false 并结束)
E -- 是 --> G(计算中间值 mid)
G --> H(计算对应行号 row 等于 mid 除以 n)
H --> I(计算对应列号 col 等于 mid 取模 n)
I --> J{matrix 所在位置的值等于 target}
J -- 是 --> K(输出 true 并结束)
J -- 否 --> L{matrix 所在位置的值小于 target}
L -- 是 --> M(更新 left 等于 mid 加 1)
L -- 否 --> N(更新 right 等于 mid 减 1)
M --> E
N --> E
六、 读题关键词总结
在 NOI 竞赛中,这类题目的题眼通常隐藏在以下词汇中:
-
“每行……递增” & “第一行大于前一行最后一位”:
- 关键词:递增 (Sorted)、大于 (Greater than)。
- 暗示:看到“有序”或“单调”,第一反应必须是二分查找。
-
“ 矩阵”:
- 关键词:矩阵维度。
- 暗示:需要注意边界处理,以及一维与二维下标的相互转换。
-
“时间/空间限制”:
- 暗示:虽然本题数据范围小,但在大型比赛中,如果数据范围达到 ,必须使用 算法,而不能使用 的逐行遍历。
教练寄语:这道题是把“一维二分”披上了“二维矩阵”的外衣。学会透过现象看本质,寻找数据背后的单调性,是进阶金牌选手的必经之路!加油!