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

题目简述

二维矩阵满足:

  • 每一行从左到右递增

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

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

例如:

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 是合法返回值,但不是合法下标
相关推荐
纽扣66726 分钟前
【算法进阶之路】链表进阶:删除、合并、回文与排序全解析
数据结构·算法·链表
消失的旧时光-194344 分钟前
统一并发模型:线程、Reactor、协程本质是一件事(从线程到协程 · 第6篇·终章)
java·python·算法
智者知已应修善业1 小时前
【51单片机不用数组动态数码管显示字符和LED流水灯】2023-10-3
c++·经验分享·笔记·算法·51单片机
AI进化营-智能译站2 小时前
ROS2 C++开发系列16-智能指针管理传感器句柄|告别ROS2节点内存泄漏与野指针
java·c++·算法·ai
米饭不加菜2 小时前
机器人矩阵运算MATLAB计算
matlab·矩阵·机器人
CS创新实验室2 小时前
从盘边到芯端——硬盘接口七十年变迁史
算法·磁盘调度
xvhao20133 小时前
单源、多源最短路
数据结构·c++·算法·深度优先·动态规划·图论·图搜索算法
MATLAB代码顾问3 小时前
多种群协同进化算法(MPCE)求解大规模作业车间调度问题——附MATLAB代码
开发语言·算法·matlab
FQNmxDG4S3 小时前
JVM内存模型详解:堆、栈、方法区与垃圾回收
java·jvm·算法
We་ct3 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·leetcode·typescript·动态规划