71 搜索二维矩阵

搜索二维矩阵

    • [题解1 Z字查找(tricky)](#题解1 Z字查找(tricky))
    • [题解2 一次二分查找](#题解2 一次二分查找)
    • [题解3 两次二分查找](#题解3 两次二分查找)

给你一个满足下述两条属性的 m x n 整数矩阵:

每行中的整数从左到右按非严格递增顺序排列
每行的第一个整数大于前一行的最后一个整数。

给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 100
  • − 1 0 4 -10^4 −104 <= matrix[i][j], target <= 1 0 4 10^4 104

题解1 Z字查找(tricky)

cpp 复制代码
class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        // z字查找的思路,适用于每行有序、每列有序的情形
        // 但这题的条件更强,即如果按行优先来看下标小的元素总是小于下标大的,直接二分会更快
        int m = matrix.size(), n = matrix[0].size();
        int r = 0, c = n-1;
        while(r >= 0 && c >= 0 && r < m && c < n){
            if(target > matrix[r][c]){
                r ++;
            }else if(target < matrix[r][c]){
                c --;
            }else return true;
        }
        return false;
    }
};

题解2 一次二分查找

cpp 复制代码
class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size(), n = matrix[0].size();
        // 按行合并(torch.cat(dim = 0))
        // 1234 2345 ...
        int l = 0;
        // 1D数组 尾下标
        int r = m*n-1;
        while(l <= r){
            int mid = l + (r-l)/2;
            // row = mid/n; column =mid%n
            if(matrix[mid/n][mid%n] == target) return true;
            else if(matrix[mid/n][mid%n] > target){
                r = mid-1;
            }else{
                l = mid+1;
            }
        }
        return false;
    }
};

题解3 两次二分查找

cpp 复制代码
class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
    	// 从第一列找第一个大于target的下标 row
    	// 这么做是因为题目限制:每行的第一个整数大于前一行的最后一个整数
        auto row = upper_bound(matrix.begin(), matrix.end(), target, [](const int b, const vector<int> &a) {
            return b < a[0];
        });
        // 如果是第一行说明第一个数就大于target,整个matrix都大于target
        if (row == matrix.begin()) {
            return false;
        }
        // 上一行可能有target
        --row;
        // stl 二分
        return binary_search(row->begin(), row->end(), target);
    }
};
相关推荐
小欣加油16 分钟前
leetcode287寻找重复数
数据结构·c++·算法·leetcode
尽兴-1 小时前
2.1 向量基础:Embedding、余弦相似度、欧氏距离、向量检索
算法·embedding·欧氏距离·向量检索·余弦相似度
Black蜡笔小新1 小时前
自动化AI算法训练服务器DLTM训推一体工作站赋能多行业智能化升级
人工智能·算法·自动化
怪兽学LLM1 小时前
LeetCode 438 找到字符串中所有字母异位词(Python 固定滑动窗口+字符计数解法)
python·算法·leetcode
满怀冰雪2 小时前
第04篇-双指针算法-从有序数组到回文判断的高频解法
java·算法
CC数学建模2 小时前
2026年江西省研究生数学建模竞赛1题:空间数据分析中的过拟合识别完整思路、代码、模型、文章,全网首发高质量分享!
python·算法·数学建模
leo__5202 小时前
MATLAB实现牧羊人算法
开发语言·算法·matlab
Gauss松鼠会2 小时前
【GaussDB】GaussDB SMP特性调优详解
java·服务器·前端·数据库·sql·算法·gaussdb
Tisfy2 小时前
LeetCode 3689.最大子数组总值 I:What The Medium
算法·leetcode·题解·贪心·模拟·脑筋急转弯
葬送的代码人生2 小时前
JavaScript 数组完全指南:从入门到实战
前端·javascript·算法