LeetCode题目74:搜索二维矩阵

ops/2024/10/18 18:23:54/

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python
欢迎加入社区:码上找工作
作者专栏每日更新:
LeetCode解锁1000题: 打怪升级之旅
python数据分析可视化:企业实战案例
python源码解读
备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

题目描述

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

  • 每行中的整数从左到右按升序排列。
  • 每行的第一个整数大于前一行的最后一个整数。
输入格式
  • matrix:一个二维整数数组。
  • target:一个整数,表示需要查找的目标值。
输出格式
  • 返回一个布尔值,表示矩阵中是否存在目标值。

示例

示例 1
输入:
matrix = [[1,   3,  5,  7],[10, 11, 16, 20],[23, 30, 34, 50]
],
target = 3
输出: true
示例 2
输入:
matrix = [[1,   3,  5,  7],[10, 11, 16, 20],[23, 30, 34, 50]
],
target = 13
输出: false

方法一:二分查找

解题步骤
  1. 将二维矩阵映射为一维数组:利用矩阵行列的关系,将二维索引转换为一维索引进行二分查找。
  2. 计算一维索引对应的行和列:一维索引 mid 可以映射回二维索引 matrix[mid // n][mid % n],其中 n 是矩阵的列数。
完整的规范代码
python">def searchMatrix(matrix, target):"""使用二分查找判断矩阵中是否存在目标值:param matrix: List[List[int]], 输入的二维矩阵:param target: int, 需要查找的目标值:return: bool, 矩阵中是否存在目标值"""if not matrix or not matrix[0]:return Falsem, n = len(matrix), len(matrix[0])left, right = 0, m * n - 1while left <= right:mid = (left + right) // 2mid_value = matrix[mid // n][mid % n]if mid_value == target:return Trueelif mid_value < target:left = mid + 1else:right = mid - 1return False# 示例调用
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 3))  # 输出: True
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 13))  # 输出: False
算法分析
  • 时间复杂度:(O(\log(m \times n))),其中 mn 是矩阵的行数和列数。
  • 空间复杂度:(O(1)),不使用额外空间。

方法二:逐行二分查找

解题步骤
  1. 遍历每一行:对矩阵的每一行使用二分查找。
  2. 应用二分查找:在每一行中应用二分查找算法查找目标值。
完整的规范代码
python">def searchMatrix(matrix, target):"""对矩阵的每一行进行二分查找:param matrix: List[List[int]], 输入的二维矩阵:param target: int, 需要查找的目标值:return: bool, 矩阵中是否存在目标值"""n = len(matrix[0])for row in matrix:left, right = 0, n - 1while left <= right:mid = (left + right) // 2if row[mid] == target:return Trueelif row[mid] < target:left = mid + 1else:right = mid - 1return False# 示例调用
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 3))  # 输出: True
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 13))  # 输出: False
算法分析
  • 时间复杂度:(O(m \log n)),每行执行一次二分查找。
  • 空间复杂度:(O(1)),不需要额外空间。

方法三:分块查找

解题步骤
  1. 分块:将矩阵视为多个块,每个块是一行。
  2. 分块二分查找:对每个块应用二分查找。
完整的规范代码
python">def searchMatrix(matrix, target):"""使用分块的方法查找矩阵中的目标值:param matrix: List[List[int]], 输入的二维矩阵:param target: int, 需要查找的目标值:return: bool, 矩阵中是否存在目标值"""row, col = 0, len(matrix[0]) - 1while row < len(matrix) and col >= 0:if matrix[row][col] == target:return Trueelif matrix[row][col] > target:col -= 1else:row += 1return False# 示例调用
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 3))  # 输出: True
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 13))  # 输出: False
算法分析
  • 时间复杂度:(O(m + n)),最坏情况下需要遍历矩阵的一行和一列。
  • 空间复杂度:(O(1)),使用固定的空间。

方法四:逐行查找

解题步骤
  1. 逐行查找:遍历每一行,对每一行使用线性搜索。
  2. 线性搜索:在每行中线性地查找目标值。
完整的规范代码
python">def searchMatrix(matrix, target):"""使用逐行查找的方法查找矩阵中的目标值:param matrix: List[List[int]], 输入的二维矩阵:param target: int, 需要查找的目标值:return: bool, 矩阵中是否存在目标值"""for row in matrix:if target in row:return Truereturn False# 示例调用
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 3))  # 输出: True
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 13))  # 输出: False
算法分析
  • 时间复杂度:(O(m \times n)),最坏情况下需要检查每个元素。
  • 空间复杂度:(O(1)),不使用额外空间。

方法五:对角线查找

解题步骤
  1. 对角线遍历:从矩阵的右上角开始,根据目标值与当前值的比较决定是向左移动还是向下移动。
  2. 对角线移动:如果当前值大于目标值,则向左移动;如果当前值小于目标值,则向下移动。
完整的规范代码
python">def searchMatrix(matrix, target):"""使用对角线查找方法查找矩阵中的目标值:param matrix: List[List[int]], 输入的二维矩阵:param target: int, 需要查找的目标值:return: bool, 矩阵中是否存在目标值"""if not matrix:return Falserow, col = 0, len(matrix[0]) - 1while row < len(matrix) and col >= 0:if matrix[row][col] == target:return Trueelif matrix[row][col] > target:col -= 1else:row += 1return False# 示例调用
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 3))  # 输出: True
print(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 13))  # 输出: False
算法分析
  • 时间复杂度:(O(m + n)),可能需要遍历矩阵的一行或一列。
  • 空间复杂度:(O(1)),使用固定的空间。

不同算法的优劣势对比

特征方法一:二分查找方法二:逐行二分查找方法三:分块查找方法四:逐行查找方法五:对角线查找
时间复杂度(O(log(m * n)))(O(m log n))(O(m + n))(O(m * n))(O(m + n))
空间复杂度(O(1))(O(1))(O(1))(O(1))(O(1))
优势高效,适用于大矩阵针对行有序的优化快速且直观简单易实现从右上角开始,直观
劣势需要理解一维映射多次二分查找需要理解移动规则效率较低需要理解移动逻辑

应用示例

数据库查询优化:在处理类似矩阵的数据结构时,如数据库表或二维数据集,使用这些算法可以优化查询操作,特别是在数据有序时。

游戏开发:在游戏开发中,可以使用这些技术来优化空间搜索,例如寻路算法或在网格上快速定位目标。

机器学习:在机器学习数据预处理阶段,这些方法可以用于快速处理和筛选特征矩阵,尤其是在进行特征选择和异常检测时。


http://www.ppmy.cn/ops/20784.html

相关文章

C#访问关键字this和base有什么作用

在C#中&#xff0c;关键字 this 和 base 分别用于引用当前实例和基类实例的成员。它们的作用如下&#xff1a; this 关键字&#xff1a; this 关键字用于引用当前实例的成员&#xff0c;包括字段、方法和属性。 当类的成员与局部变量同名时&#xff0c;可以使用 this 关键字来…

64位整数高低位的数据获取与赋值操作探讨

参考本篇->LOWORD和HIWORD函数_hidword-CSDN博客 一&#xff0c;如何获取一个64位整数的高32位和低32位 原理其实很简单&#xff1a; 解释一些概念 ①十六进制和二进制直接挂钩 一个十六位的十六进制数【0XAABBCCDD12345678】转为二进制的过程是把其中的每个数转为对应的二…

【Jenkins】持续集成与交付 (五):Jenkins用户权限管理

【Jenkins】持续集成与交付 (五):Jenkins用户权限管理 1、安装插件(Role-based Authorization Strategy)2、开启权限全局安全配置3、创建角色4、创建用户5、给用户分配角色6、测试权限💖The Begin💖点点关注,收藏不迷路💖 1、安装插件(Role-based Authorization Stra…

为什么要学音视频?

一直都在说“科技改变生活”&#xff0c;现实告诉我们这是真的。 随着通信技术和 5G 技术的不断发展和普及&#xff0c;不仅拉近了人与人之间的距离&#xff0c;还拉近了人与物&#xff0c;物与物之间的距离&#xff0c;万物互联也变得触手可及。 基于此背景下&#xff0c;音…

【JavaEE网络】深入理解Socket套接字及其在网络编程中的应用

目录 Socket套接字UDP VS TCP有连接 VS 无连接可靠传输 VS 不可靠传输面向字节流 VS 面向数据报 全双工 VS 半双工 UDP数据报套接字编程DatagramSocket APIDatagramPacket APIInetSocketAddress APIUDP回显客户端服务器服务器和客户端的工作流程UDP翻译客户端服务器 Socket套接…

安全作业-1

1. windows登录的明文密码&#xff0c;存储过程是怎么样的&#xff0c;密文存在哪个文件下&#xff0c;该文件是否可以打开&#xff0c;并且查看到密文 用户在登录界面输入用户名和密码。Windows登录进程(winlogon.exe)接收用户的输入&#xff0c;并准备进行身份验证。Lsass处…

【数据结构】图的应用(最小生成树、拓扑排序、最短路径等)

文章目录 最小生成树概念Prim算法基于邻接表的Prim算法&#xff1a;基于邻接矩阵的Prim算法 Kruskal算法基于邻接表的Kruskal算法&#xff1a;基于邻接矩阵的Kruskal算法&#xff1a; 有向无环图及其应用拓扑排序概念基于邻接表的拓扑排序算法&#xff1a;基于邻接矩阵的拓扑排…

csdn的复制代码功能如何实现

页面布局分析&#xff1a; 按钮在文本框里面&#xff0c;所以文本框是父元素&#xff0c;按钮是子元素。要使得按钮在文本框的右上角&#xff0c;需要使用绝对定位。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8">…