题目描述
思路解析动画文字版
挨个看每个格子当然能找到,可这把「整体有序」这个大礼包完全浪费了。题目都把有序明牌摆你面前了,必须把二分用起来。
转折:既然拉直就是升序数组,那就对下标 0..m·n−1 这条「虚拟数组」直接二分。要取第 mid 个数时,行号 = mid // n、列号 = mid % n(n 是列数)。这样根本不用真把矩阵拼起来,O(1) 就能换算回原矩阵取值。
准备 · 拉直成升序数组:把矩阵拉直就是这条数组。l=0、r=7,范围是全部 8 个数。要找 target = 3,全程不真拼数组,靠 mid//n、mid%n 回原矩阵取值。
第 1 轮 · 取 mid:中点 mid = (0+7)//2 = 3。换算回矩阵:行 = 3//4 = 0、列 = 3%4 = 3,取到 matrix[0][3] = 7。拿它和 target = 3 比。
第 1 轮 · 判断收缩:7 比 3 大,目标在左半边。把 r 收到 mid−1 = 2,右边那半(含 7,灰)整个丢掉。范围缩到 [0, 2]。
第 2 轮 · 取 mid:现在范围是 [0, 2]。新中点 mid = (0+2)//2 = 1,换算:行 = 1//4 = 0、列 = 1%4 = 1,取到 matrix[0][1] = 3。
第 2 轮 · 命中!:matrix[0][1] 正好等于 3!返回 true。全程只看了 2 个数,靠的就是 mid//n、mid%n 这一步换算。
再看个找不到的 · target=4:换个例子:找 4。数组里没有 4,看二分怎么靠 l 越过 r 收尾。
4 · mid=3 → 7 大于 4:mid=3 取到 7,比 4 大,r 收到 2。范围 [0, 2]。
4 · mid=1 → 3 小于 4:mid=1 取到 3,比 4 小,l 收到 2。现在 l 和 r 都指向 2。
4 · mid=2 → 5 大于 4,l 越过 r:mid=2 取到 5,比 4 大,r 收到 1。这时 l(2) 越过了 r(1),范围空了,循环结束,返回 false。
看到「每行升序 + 行间衔接」,就把二维拉直当一维,用 mid // n 和 mid % n 来回换算下标,剩下交给二分。这是把高维问题压成一维有序的经典技巧。
边界三连:三种边界先想清楚。
面试官常追问:三个高频追问,答法记牢。
参考代码
class Solution: def searchMatrix(self, matrix, target): m, n = len(matrix), len(matrix[0]) l, r = 0, m * n - 1 while l <= r: mid = (l + r) // 2 x = matrix[mid // n][mid % n] # 一维下标映射回二维 if x == target: return True if x < target: l = mid + 1 else: r = mid - 1 return False复杂度
- 时间复杂度:O(log(m·n)),在 m·n 个数上二分,每轮砍一半
- 空间复杂度:O(1),只用 l、r、mid 几个变量,不真拼数组
可套用的代码模板
记牢换算公式:行 = mid // n、列 = mid % n,n 是列数。这是全题唯一的坎,背下来普通二分就能解二维。
Python
l, r = 0, m * n - 1while l <= r: mid = (l + r) // 2 v = matrix[mid // n][mid % n] # 行 = mid//n,列 = mid%n if v == target: return True elif v < target: l = mid + 1 else: r = mid - 1return False易错点
面试追问把动画讲成自己的话
追问核心思路是什么?
追问和 LC240(行列各自有序但行间不衔接)有何不同?
追问复杂度多少?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
爱吃香蕉的珂珂
LeetCode 875 · 中等 · 沿着 二分查找 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题