从零开始写算法——二分-搜索二维矩阵

题目简述

二维矩阵满足:

  • 每一行从左到右递增

  • 每一行首元素大于上一行最后一个元素

这意味着矩阵整体呈现严格递增的一维序列

例如:

cpp 复制代码
[
  [1, 3, 5, 7],
  [10,11,16,20],
  [23,30,34,60]
]

可以视为:

cpp 复制代码
1,3,5,7,10,11,16,20,23,30,34,60

核心思想:二维转一维

二维矩阵按行拼接,即坐标映射:

cpp 复制代码
i → (i / n, i % n)

其中:

  • n 是列数

  • i / n 是行号

  • i % n 是列号

二分查找代码(闭区间写法)

cpp 复制代码
class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size();
        int n = matrix[0].size();

        int left = 0;
        int right = m * n - 1;  // 一维区间 [0, m*n-1]

        while (left <= right) {
            int mid = left + (right - left) / 2;

            // mid / n → 行
            // mid % n → 列
            if (matrix[mid / n][mid % n] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }

        // 💥 关键:避免越界访问 matrix[left]
        if (left == m * n) return false;

        return matrix[left / n][left % n] == target;
    }
};

重点:闭区间二分为什么会越界?

闭区间写法:

cpp 复制代码
left = 0
right = size-1
while (left <= right)

这一写法的返回值有一个特点:

最终的 left 可能等于 size

这是完全符合设计的,因为:

  • 如果所有元素都小于 target

    ⇒ 返回应该是第一个大于等于 target 的位置

    ⇒ 也就是 size

    ⇒ left == size

但问题来了:

你一旦直接访问:

cpp 复制代码
nums[left]

left == size

cpp 复制代码
nums[size]  // 非法访问,越界 ❌

如何避免越界?

只要使用闭区间写法,就必须判断:

cpp 复制代码
if (left == size) return ...

总结

闭区间写法凡是涉及到访问nums[size]一定要注意边界访问越界问题。

二维搜索矩阵的核心:

  • 把矩阵视为一维递增数组

  • mid / nmid % n 完成坐标映射

闭区间写法最大的坑:

最终 left 可能等于数组长度(size),访问会越界

所以必须判断:

cpp 复制代码
if (left == size) return ...;

为什么需要判断?

  • 因为 left = size 是合法返回值,但不是合法下标
相关推荐
地平线开发者12 小时前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮13 小时前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者13 小时前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶
罗西的思考13 小时前
AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
人工智能·算法·机器学习
HXhlx17 小时前
CART决策树基本原理
算法·机器学习
Wect17 小时前
LeetCode 210. 课程表 II 题解:Kahn算法+DFS 双解法精讲
前端·算法·typescript
颜酱18 小时前
单调队列:滑动窗口极值问题的最优解(通用模板版)
javascript·后端·算法
Gorway1 天前
解析残差网络 (ResNet)
算法
拖拉斯旋风1 天前
LeetCode 经典算法题解析:优先队列与广度优先搜索的巧妙应用
算法
Wect1 天前
LeetCode 207. 课程表:两种解法(BFS+DFS)详细解析
前端·算法·typescript