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

题目简述

二维矩阵满足:

  • 每一行从左到右递增

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

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

例如:

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 是合法返回值,但不是合法下标
相关推荐
dingzd952 小时前
跨平台账号矩阵高效协同术
线性代数·矩阵·web3·facebook·tiktok·instagram·clonbrowser
Kuo-Teng2 小时前
LeetCode 19: Remove Nth Node From End of List
java·数据结构·算法·leetcode·链表·职场和发展·list
Kuo-Teng2 小时前
LeetCode 21: Merge Two Sorted Lists
java·算法·leetcode·链表·职场和发展
2301_800399723 小时前
stm32 printf重定向到USART
java·stm32·算法
顾安r4 小时前
11.15 脚本算法 加密网页
服务器·算法·flask·html·同态加密
前端小L4 小时前
图论专题(四):DFS的“回溯”之舞——探寻「所有可能路径」
算法·深度优先·图论
司铭鸿4 小时前
数学图论的艺术:解码最小公倍数图中的连通奥秘
运维·开发语言·算法·游戏·图论
元亓亓亓4 小时前
LeetCode热题100--39. 组合总和
算法·leetcode·职场和发展
2401_841495645 小时前
【LeetCode刷题】找到字符串中所有字母异位词
数据结构·python·算法·leetcode·数组·滑动窗口·找到字符串中所有字母异位词