当前:LC240 · 搜索二维矩阵 II · 首次出现于 Day 53 · 路径:顶栏「56天打卡」→ 点击 LC 题号 → 逐题动画

LC240 · Search a 2D Matrix II · 矩阵 / 双指针

搜索二维矩阵 II:从右上角走

每行从左到右递增,每列从上到下递增。站在右上角:当前数太大就往左丢掉这一列,太小就往下丢掉这一行。

从 (0, n−1) 出发。当前值大于 target 则列号减一(这一列往下只会更大);小于 target 则行号加一(这一行往左只会更小)。相等即找到,走出边界即没有。时间 O(m+n),空间 O(1)。

时间 O(m+n)空间 O(1)结论先行 · 全文约 6 节
导读

给你一个矩阵,每一行从左到右递增,每一列从上到下递增。判断 target 在不在里面。行与行之间没有「上一行末尾小于下一行开头」这种全局顺序,不能当成一整条有序数组对半切。

主例五行五列,第一行 1 4 7 11 15,第二行 2 5 8 12 19,后面三行同样向右、向下变大。target = 5,在第二行第二列,应当返回 true。

每行二分是 O(m log n),能做对。本文要回答:为什么右上角一步就能丢掉整行或整列,以及主例从 15 走到 5 中间经过哪些格子。

Go:右上角 Z 字形

solution.goGo
func searchMatrix(matrix [][]int, target int) bool {
m, n := len(matrix), len(matrix[0])
r, c := 0, n-1
for r < m && c >= 0 {
if matrix[r][c] == target {
return true
} else if matrix[r][c] > target {
c--
} else {
r++
}
}
return false
}

1r、c 从右上角起步。循环条件是还在矩阵里:行向下不越界,列向左不越界。

2大于 target 只减 c,小于只加 r。主例 15→11→7→4 都是减 c,4 到 5 是加 r。

3走出边界还没相等,就是没有。不要在分支里同时改 r 和 c。

总结

从右上角走:大了丢列往左,小了丢行往下。主例 15 经 4 落到 5。

  • 左上角两条路都变大,一步排除不了一片。右上角或左下角才是拐点。
  • 主例路径是 (0,4)→…→(0,1)→(1,1),只向左或向下。
  • 最多 m+n 步。越界即不存在。LC74 多了全局有序,才能整表二分。
同族题目
LC74搜索二维矩阵LC1351统计有序矩阵中的负数LC378有序矩阵中第 K 小的元素