当前位置: 首页 > news >正文

Leetcode力扣解题记录--第240题(矩阵搜索)

题目链接:240. 搜索二维矩阵 II - 力扣(LeetCode)

题目描述

编写一个高效的算法来搜索 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

题目作答

解决这个问题的核心思想是利用矩阵的结构特性,逐步缩小搜索范围。一个低效的方法是逐行进行二分查找,时间复杂度为 O(m log n),但这并未完全利用“列也排序”的特性。

最高效的算法是“Z”字形或“马鞍点”查找法。该方法的巧妙之处在于选择一个合适的起点,使得每一步比较后都能明确地排除一行或一列,从而将搜索空间线性地减小。

这个理想的起点是矩阵的右上角(或者左下角也可以)。为什么是右上角呢?

  1. 选择起点:我们将搜索指针初始化在矩阵的右上角,即 (row = 0, col = n - 1)。

  2. 比较与移动

    • 令当前元素为 current = matrix[row][col]。

    • 如果 current == target:恭喜,我们找到了目标值,直接返回 true。

    • 如果 current > target:因为当前行的元素从左到右是递增的,所以 target 不可能在 current 的右边。同时,因为当前列的元素从上到下是递增的,所以 target 也不可能在 current 的下方(下方的元素都比current大)。因此,唯一可能的位置是在 current 的左边。我们可以安全地排除当前所在的整列,将指针向左移动一位,即 col--。

    • 如果 current < target:因为当前列的元素从上到下是递增的,所以 target 不可能在 current 的上方。同时,因为当前行的元素从左到右是递增的,所以 target 也不可能在 current 的左边(左边的元素都比current小)。因此,唯一可能的位置是在 current 的下方。我们可以安全地排除当前所在的整行,将指针向下移动一位,即 row++。

  3. 终止条件:我们重复上述比较和移动的过程,直到找到 target,或者指针移出了矩阵的边界(row 超出下边界或 col 超出左边界)。如果循环结束仍未找到,说明矩阵中不存在该目标值。

这个算法在每一步都稳定地排除一行或一列,其路径最多走 m + n 步,因此时间复杂度为 O(m + n),空间复杂度为 O(1),非常高效。

class Solution {
public:bool searchMatrix(vector<vector<int>>& matrix, int target) {// 处理边界情况if (matrix.empty() || matrix[0].empty()) {return false;}int m = matrix.size();int n = matrix[0].size();// 1. 从矩阵的右上角开始搜索int row = 0;int col = n - 1;// 循环条件:指针在矩阵边界内while (row < m && col >= 0) {int current = matrix[row][col];if (current == target) {// 2. 找到了目标值return true;} else if (current > target) {// 3. 当前值大于目标值,排除当前列,向左移动col--;} else { // current < target// 4. 当前值小于目标值,排除当前行,向下移动row++;}}// 如果循环结束仍未找到,说明目标值不存在return false;}
};

http://www.dtcms.com/a/293514.html

相关文章:

  • 数据科学与大数据技术和统计学有什么区别?​
  • 关于针对 DT_REG 出现红色波浪线的问题(编译错误/IDE警告),以下是 精准解决方案,保持你的代码功能完全不变:
  • 【Linux-云原生-笔记】Haproxy相关
  • 基于Python(Django)+MongoDB实现的(Web)新闻采集和订阅系统
  • 模拟实现消息队列项目
  • 使用PEghost恢复系统(笔记版)
  • OpenEuler系统架构下编译redis的RPM包
  • [Mediatek] MTK openwrt-21.02 wifi 没启动问题
  • Android Multidex 完全解析:解决64K方法数限制
  • Java 虚拟线程在高并发微服务中的实战经验分享
  • 从0开始学习R语言--Day55--弹性网络
  • TDengine 的 HISTOGRAM() 函数用户手册
  • LabVIEW激光雷达障碍物识别
  • #C语言——学习攻略:操作符的探索(二)
  • 架构师--基于常见组件的微服务场景实战
  • VI Server 操控 LabVIEW 工程
  • DeepSeek Janus Pro本地部署与调用
  • 基于Trae IDE与MCP实现网页自动化测试的最佳实践
  • CI/CD与DevOps集成方法
  • 希尔排序cc
  • 无人机减震模块技术解析
  • Java冒泡排序的不同实现
  • 无人机吊舱减震球模块运行分析
  • 如何在Pico等Android头显中实现无人机低延迟RTMP全景巡检画面播放
  • Cursor(vscode)一些设置
  • 【基于OpenCV的图像处理】图像预处理之图像色彩空间转换以及图像灰度化处理
  • 高亮匹配关键词样式highLightMatchString、replaceHTMLChar
  • 图论的题目整合(Dijkstra)
  • 货车手机远程启动功能的详细使用步骤及注意事项
  • Elasticsearch 字段值过长导致索引报错问题排查与解决经验总结