LeetCode题目74:搜索二维矩阵

作者介绍: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 是矩阵的列数。
完整的规范代码
def searchMatrix(matrix, target):
    """
    使用二分查找判断矩阵中是否存在目标值
    :param matrix: List[List[int]], 输入的二维矩阵
    :param target: int, 需要查找的目标值
    :return: bool, 矩阵中是否存在目标值
    """
    if not matrix or not matrix[0]:
        return False
    m, n = len(matrix), len(matrix[0])
    left, right = 0, m * n - 1
    while left <= right:
        mid = (left + right) // 2
        mid_value = matrix[mid // n][mid % n]
        if mid_value == target:
            return True
        elif mid_value < target:
            left = mid + 1
        else:
            right = mid - 1
    return 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. 应用二分查找:在每一行中应用二分查找算法查找目标值。
完整的规范代码
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 - 1
        while left <= right:
            mid = (left + right) // 2
            if row[mid] == target:
                return True
            elif row[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
    return 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. 分块二分查找:对每个块应用二分查找。
完整的规范代码
def searchMatrix(matrix, target):
    """
    使用分块的方法查找矩阵中的目标值
    :param matrix: List[List[int]], 输入的二维矩阵
    :param target: int, 需要查找的目标值
    :return: bool, 矩阵中是否存在目标值
    """
    row, col = 0, len(matrix[0]) - 1
    while row < len(matrix) and col >= 0:
        if matrix[row][col] == target:
            return True
        elif matrix[row][col] > target:
            col -= 1
        else:
            row += 1
    return 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. 线性搜索:在每行中线性地查找目标值。
完整的规范代码
def searchMatrix(matrix, target):
    """
    使用逐行查找的方法查找矩阵中的目标值
    :param matrix: List[List[int]], 输入的二维矩阵
    :param target: int, 需要查找的目标值
    :return: bool, 矩阵中是否存在目标值
    """
    for row in matrix:
        if target in row:
            return True
    return 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. 对角线移动:如果当前值大于目标值,则向左移动;如果当前值小于目标值,则向下移动。
完整的规范代码
def searchMatrix(matrix, target):
    """
    使用对角线查找方法查找矩阵中的目标值
    :param matrix: List[List[int]], 输入的二维矩阵
    :param target: int, 需要查找的目标值
    :return: bool, 矩阵中是否存在目标值
    """
    if not matrix:
        return False
    row, col = 0, len(matrix[0]) - 1
    while row < len(matrix) and col >= 0:
        if matrix[row][col] == target:
            return True
        elif matrix[row][col] > target:
            col -= 1
        else:
            row += 1
    return 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.mfbz.cn/a/579986.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

matlab回归学习

前言 所谓回归学习即预测&#xff0c;便是由已知的数据推测未知的数据&#xff0c;利用转速与转矩来推测电流。 1、数据准备 下面虚拟一组转速转矩以及电流数据。 speed [100 220 330 440 550 660]; torque [200 300 400 500 700 900]; I [400 500 603 739 821 912]; arr …

职场进阶秘籍:张驰咨询的六西格玛黑带培训!

你们是否对“六西格玛黑带培训”感到好奇&#xff1f;别担心&#xff0c;这不是什么遥不可及的概念&#xff0c;而是一次能让你职场生涯焕然一新的机会&#xff01; 六西格玛黑带培训在张驰咨询 在张驰咨询&#xff0c;我们提供的六西格玛黑带培训&#xff0c;就像是一把为你量…

mysql-sql-练习题-2

日期topN 日期最值 topN 任意区间topN 每年温度top2建表排名函数万能公式&#xff08;条关&#xff09; 任意区间 各科第1,3,5名排名函数万能公式 日期 本周过生日 -- 本周表示 加减日期 格式化 拼接 select * from student where date_format(s_age,concat(year(curdate()),…

微信小程序开发:2.小程序组件

常用的视图容器类组件 View 普通的视图区域类似于div常用来进行布局效果 scroll-view 可以滚动的视图&#xff0c;常用来进行滚动列表区域 swiper and swiper-item 轮播图的容器组件和轮播图的item项目组件 View组件的基本使用 案例1 <view class"container"&…

【FPGA】优化设计指南(一):设计原则

目录 避免采用不可综合的语句设计时采用同步的时钟组合逻辑与毛刺异步复位与同步复位动态分析与静态分析功能流水线时序违例乒乓操作面积和速度的平衡避免采用不可综合的语句 1.#1000延时语句 2.除法运算/,除非除数为2的整次幂 3.实数类型不可综合(real) 4.综上,使用可综合…

远程连接docker,实现本地发布版本到服务器

最近在学jenkins的时候&#xff0c;发现涉及到了docker的远程发布调用。后续应该还要自己搭建一个docker的本地仓库。 简单描述一下具体是如何实现的&#xff1a; 1、将docker的服务器开启2375端口&#xff08;注意&#xff0c;这里的开启是将端口直接暴露出去&#xff0c;不用…

【python技术】akshare爬取A股最新业绩预告保存进excel的简单示例

最近A股上市公司陆续在出年报和一季度报了&#xff0c; 心里寻思着要不用python把这些数据爬取下来分析下&#xff0c;说干就干。 数据来源网站东方财富&#xff1a;https://data.eastmoney.com/bbsj/ 我这个人比较懒&#xff0c;直接用akshare封装的方法来搞定 之前用aksha…

uniapp 对接谷歌第三方登录

1.登录谷歌开发者后台 https://console.developers.google.com/ 2.添加凭证 3.拿到客户端id后&#xff0c;项目中配置google登录&#xff1a; 示例代码&#xff1a; async googleLogin(){const { provider } await uni.getProvider({ service:oauth })if(provider.includes…

【WBS工作分解结构】项目管理必会的思维分析工具 09

关于工作中“量”的分解&#xff0c;最核心的问题是投入工作量如何相对准确的评估。&#xff1a; WBS工作包分解法&#xff1a;将重点工作任务拆分为具体的子任务&#xff0c;然后分别对各个子任务进行估算&#xff0c;最后将各子任务时间求和&#xff08;原则上每个子任务不可…

Springboot+Vue项目-基于Java+MySQL的非物质文化网站设计与实现(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

机器学习高频问答题总结

机器学习问答题总结 第一章 线性回归1.什么是线性回归&#xff1f;解释主要原理2.解释线性回归中最小二乘法的原理吗&#xff1f;3.如何评估线性回归模型的性能&#xff1f;4.线性回归中正则化的目的是什么吗&#xff1f;L1正则化和L2正则化有什么不同&#xff1f; 第二章 逻辑…

北京人形机器人创新中心发布新款人形机器人平台,奔跑速度可达6km/h,可适应多种地形环境...

今天&#xff0c;北京人形机器人创新中心发布了一款人形机器人&#xff0c;名叫“天工”&#xff0c;拥有更加自然和拟人的步行姿态&#xff0c;支持奔跑&#xff0c;且奔跑速度可达到6km/h&#xff0c;也可以适应不同的地形环境&#xff0c;比如楼梯和坡道地形。 下面是这款机…

探索矿业数字化平台:实现智能化采矿与管理

随着信息技术的迅猛发展&#xff0c;矿业领域也在逐步实现数字化转型。数字化平台的出现为矿业企业带来了更高效、更智能的采矿与管理方式。本文将探讨矿业数字化平台的意义、特点以及未来发展方向。 ### 1. 数字化平台的意义 传统的矿业生产和管理方式存在诸多问题&#xff…

基于ERNIR3.0模型的向量计算的开发与实践

参考&#xff1a;飞桨PaddlePaddle-源于产业实践的开源深度学习平台 自然语言处理 Paddle NLP - 检索式文本问答-理论 - VipSoft - 博客园 (cnblogs.com) 词向量&#xff08;Word Embedding&#xff09;是表示自然语言里单词的一种方法&#xff0c;即把每个词都表示为一个N维…

.net6 webapi 部署到IIS

一、发布.net6 webapi 项目 1.1 visual studio 2022右键发布到文件夹。 二、增加IIS容器 2.1 控制面板 2.2 启用或关闭Windows功能 3.3 勾选Internet Information Services,点击确定进行安装 三、部署webapi到IIS 3.1 安装 dotnet-hosting-6.0.29-win.exe 3.2 创建应用…

vue 项目关于不同分辨率的电脑网页适配方案

流式布局&#xff1a;这是一种相对灵活的布局方式&#xff0c;页面的元素宽度使用相对宽度&#xff08;例如百分比&#xff09;来定义&#xff0c;而不是使用绝对宽度&#xff08;例如像素&#xff09;。这样&#xff0c;当浏览器窗口大小变化时&#xff0c;元素会自动调整大小…

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

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

数字电路-可预置倒计时器Multisim仿真

数字电路之于FPGA意义重大。本“可预置倒计时器”设计采用施密特触发器40106作为振荡电路&#xff0c;由同步十进制可逆计数器74LSl92、译码器74LS47D和七段共阳数码管构成计时电路&#xff0c;具有启动/预置、暂停/继续计时和报警功能。紫色文字是超链接&#xff0c;点击自动跳…

Vscode配置C/C++编程环境@配置C和CPP的运行和调试环境@配置过程的相关问题@中文文件名乱码@build和debug方案组合配置

文章目录 abstractgcc/g文档和用法常见用例设置源文件编码和调试信息选型示例 目录.vscode中的相关文件说明tasks.jsonlaunch.jsonc_cpp_properties.json IDE或编辑器配置vscode配置相关指令和快捷键默认task配置和取消默认 配置文件使用vscode预置变量和环境变量环境变量的使用…

【树莓派】树莓派4B配置环境

当你在配置你的系统时&#xff0c;这些指令将会非常有用。首先&#xff0c;你可能需要设置代理&#xff0c;特别是当你在一个受限的网络环境下工作时。以下是一些指令的详细说明&#xff1a; 设置代理 export http_proxyhttp://192.168.3.2:10811 export https_proxyhttp://1…
最新文章