LeetCode——240.搜索二维矩阵 II(Search a 2D Matrix II)[中等]——分析及代码(C++、Java)

news/2025/2/21 13:10:38

LeetCode——240.搜索二维矩阵 II[Search a 2D Matrix II][中等]——分析及代码[C++、Java]

  • 一、题目
  • 二、分析及代码
    • 1. 从左下或右上搜索/Z字形查找
      • (1)思路
      • (2)代码(C++)
      • (3)结果(C++)
      • (4)代码(Java
      • (5)结果(Java
    • 2. 二分搜索
      • (1)思路
      • (2)代码
      • (3)结果
  • 三、其他

一、题目

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。

示例 1:

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true

示例 2:

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= n, m <= 300
  • -10^9 <= matrix[i][j] <= 10^9
  • 每行的所有元素从左到右升序排列
  • 每列的所有元素从上到下升序排列
  • -10^9 <= target <= 10^9

来源:力扣(LeetCode
链接:https://leetcode-cn.com/problems/search-a-2d-matrix-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、分析及代码

1. 从左下或右上搜索/Z字形查找

(1)思路

若按下标从左上角搜索,由于向下、向右数值均单调递增,导致无法准确判断搜索方向;

若从左下角搜索,则可以准确判断搜索方向:

  • 当前值 > target,搜索上方数值;
  • 当前值 < target,搜索右方数值;

可以不断迭代,直至搜索到目标 target (true) 或 超出矩阵范围(false)。

(2)代码(C++)

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int i = matrix.size() - 1, j = 0;
        while (i > -1 && j < matrix[0].size()) {
            if (matrix[i][j] > target)
                i--;
            else if (matrix[i][j] < target)
                j++;
            else   
                return true;
        }
        return false;
    }
};

(3)结果(C++)

执行用时 :64 ms, 在所有 C++ 提交中击败了 94.18% 的用户;
内存消耗 :12.6 MB, 在所有 C++ 提交中击败了 95.57% 的用户。

Java_63">(4)代码(Java

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length;
        int i = m - 1, j = 0;//搜索指针的行、列坐标
        while (i >= 0 && j < n) {//指针在矩阵范围内时
            if (matrix[i][j] == target) {//找到目标值
                return true;
            } else if (matrix[i][j] < target) {//当前元素小于目标值,增大列坐标
                j++;
            } else {//当前元素大于目标值,减小行坐标
                i--;
            }
        }
        return false;//搜索完成后未在矩阵中发现目标值
    }
}

Java_82">(5)结果(Java

执行用时 :5 ms,在所有 Java 提交中击败了 96.28% 的用户;
内存消耗 :44 MB,在所有 Java 提交中击败了 39.76% 的用户。

2. 二分搜索

(1)思路

先在矩阵的 45 度对角线上二分搜索,直至发现 target(返回true)或找到 matrix[i][i] < target < matrix[i + 1][i + 1]。

将此时的矩形划分为 4 块讨论,左上部分的数值全部小于 target,右下部分的数值全部大于 target,可跳过。

针对左下部分和右上部分的矩阵进一步二分迭代,直至发现 target。

(2)代码

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if (matrix.empty() || matrix[0].empty())
            return false;
        return search(matrix, target, 0, 0, matrix.size(), matrix[0].size());
    }

    bool search(vector<vector<int>>& matrix, int target, int li, int lj, int ri, int rj) {//参数为所搜索矩阵的左下、右上坐标
        if ((li > ri - 1) || (lj > rj - 1) || matrix[li][lj] > target || matrix[ri - 1][rj - 1] < target)
            return false;
        int li0 = li, lj0 = lj, ri0 = ri, rj0 = rj;     
        while (li < ri - 1 || lj < rj - 1) {//二分搜索对角线
            int mi = (li + ri) / 2, mj = (lj + rj) / 2;
            if (matrix[mi][mj] > target) {
                ri = mi;
                rj = mj;
            }
            else {
                li = mi;
                lj = mj;
            }
        }
        if (matrix[li][lj] == target)
            return true;
        return search(matrix, target, li + 1, lj0, ri0, lj + 1) || search(matrix, target, li0, lj + 1, li + 1, rj0);//递归搜索左下和右上矩阵
    }
};

(3)结果

执行用时 :140 ms, 在所有 C++ 提交中击败了 31.13% 的用户;
内存消耗 :13.1 MB, 在所有 C++ 提交中击败了 5.06% 的用户。

三、其他

暂无。


http://www.niftyadmin.cn/n/616547.html

相关文章

LeetCode—253.会议室 II(Meeting Rooms II)——分析及代码(C++)

LeetCode—253.会议室 II[Meeting Rooms II]——分析及代码[C]一、题目二、分析及代码1. 起止时间分别排序&#xff08;1&#xff09;思路&#xff08;2&#xff09;代码&#xff08;3&#xff09;结果三、其他一、题目 给定一个会议时间安排的数组&#xff0c;每个会议时间都…

hbase怎么修改表名?

hbase本身没有提供修改表名的命令,那如果我们需要修改表名,该怎么办呢? 可以通过snapshot的功能来实现 先来看下hbase里面有哪些表: list 我们把test1修改成test2 1,禁用表 disable test1 2,给表做快照 snapshot test1, test1_snapshot 3,克隆快照为新的表名 clone_snap…

LeetCode—279.完全平方数(Perfect Squares)——分析及代码(C++/Java)

LeetCode—279.完全平方数[Perfect Squares]——分析及代码[C/Java]一、题目二、分析及代码1. 动态规划&#xff08;1&#xff09;思路&#xff08;2&#xff09;代码&#xff08;C&#xff09;&#xff08;3&#xff09;结果&#xff08;C&#xff09;&#xff08;4&#xff0…

LeetCode—283.移动零(Move Zeroes)——分析及代码(C++)

LeetCode—283.移动零[Move Zeroes]——分析及代码[C]一、题目二、分析及代码1. 双指针 直接记录&#xff08;1&#xff09;思路&#xff08;2&#xff09;代码&#xff08;3&#xff09;结果2. 双指针 交换&#xff08;1&#xff09;思路&#xff08;2&#xff09;代码&…

U盘的文件系统为FAT32才可以同时在苹果电脑和windows电脑中正常使用

文章目录 1.驱动器F中的磁盘未被格式化。想现在格式化吗&#xff1f;2.U盘插到苹果电脑上后无法写入 1.驱动器F中的磁盘未被格式化。想现在格式化吗&#xff1f; 我之前U盘的文件系统为exFAT&#xff0c;插入Windows Server 2003系统的电脑中&#xff0c;打开时弹出上面的提示框…

Phoenix的安装和使用

直接看我的公众号吧,就不在复制了 https://mp.weixin.qq.com/s/yNAmlFPnHMqCDIXhFVLhrw 欢迎大家关注我的公众号

Java设计模式精讲—课程笔记9(第21章 观察者模式 + 第22章 备忘录模式 + 第23章 命令模式 + 第24章 中介者模式)

Java设计模式精讲—课程笔记921 观察者模式讲解Coding源码解析21.1 观察者模式讲解21.2 观察者模式coding21.3 观察者模式源码解析-jdk-guava22 备忘录模式讲解Coding源码解析22.1 备忘录模式讲解22.2 备忘录模式coding22.3 备忘录模式源码解析-spring23 命令模式讲解Coding源码…

maven打包报错java.lang.StackOverflowError解决方法

在maven项目打包的时候报错,java.lang.StackOverflowError 解决方法在setting->maven->runner->VM Options中添加 -Xss4096k 如下图所示 再次点击打包就可以了,如果还是报错的话,可以尝试把这个值在增大一点.