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);
    }
};
相关推荐
尼尔森系4 小时前
排序与算法:希尔排序
c语言·算法·排序算法
AC使者4 小时前
A. C05.L08.贪心算法入门
算法·贪心算法
冠位观测者4 小时前
【Leetcode 每日一题】624. 数组列表中的最大距离
数据结构·算法·leetcode
sushang~5 小时前
leetcode203.移除链表元素
数据结构·链表
yadanuof5 小时前
leetcode hot100 滑动窗口&子串
算法·leetcode
可爱de艺艺5 小时前
Go入门之函数
算法
武乐乐~5 小时前
欢乐力扣:旋转图像
算法·leetcode·职场和发展
a_j585 小时前
算法与数据结构(子集)
数据结构·算法·leetcode
刃神太酷啦6 小时前
树(数据结构·)
数据结构·c++·蓝桥杯c++组
清水加冰6 小时前
【算法精练】背包问题(01背包问题)
c++·算法