LeetCode刷题之搜索二维矩阵

2024 7/5 一如既往的晴天,分享几张拍的照片嘿嘿,好几天没做题了,在徘徊、踌躇、踱步。蝉鸣的有些聒噪了,栀子花花苞也都掉落啦,今天给他剪了枝,接回一楼来了。ok,做题啦!
在这里插入图片描述
图1、宿舍阳台摄,每天都是如此美景
在这里插入图片描述
图2、吃饭路上桥上摄
在这里插入图片描述
图3、桥的另一边摄
okok,做题啦!

1、题目描述

在这里插入图片描述

2、算法分析

要求设计一个高效的算法在矩阵中搜索我们想要的元素。我所能想到的就只有暴力解法:

 public boolean searchMatrix(int[][] matrix, int target) {for(int[] row : matrix ){for(int x : row){if(x == target){return true;}}}return false;   }

暴力解法感觉很爽啊,思路简单。为什么简单的解法往往性能不简单呢?收益高的往往需要更多的付出呢?空间复杂度和时间复杂度往往不能正相关呢?一切似乎都与能量守恒有关。一切似乎都被设定,而我就是一个没有台词的NPC。哈哈,太tm矫情了,矫揉造作,继续想想有没有什么好的方法。
是有的,由于矩阵每一行都是升序排列的,所以我们遍历每一行后,再进行二分查找,看目标值是否在矩阵中。

3、代码

public boolean searchMatrix(int[][] matrix, int target) {// 遍历矩阵的每一行  for(int[] row : matrix){// 对当前行执行二分查找,寻找目标值int index = binarySearch(row, target);// 如果在当前行找到了目标值(即index >= 0),则返回trueif(index >= 0){return true;}} // 如果遍历完所有行都没有找到目标值,则返回falsereturn false;}// 定义一个辅助方法,用于对一维数组进行二分查找  // 参数:nums是要搜索的一维数组,target是要搜索的目标值  // 返回值:如果找到目标值,则返回目标值在数组中的索引;如果没有找到,则返回-1public int binarySearch(int[] nums, int target){// 初始化查找范围的上下界int low = 0, high = nums.length - 1;// 当查找范围不为空时,进行查找while(low <= high){// 计算中间索引,防止溢出 int mid = (high - low) / 2 + low;// 获取中间元素的值int temp = nums[mid];// 如果中间元素等于目标值,则返回其索引if(temp == target){return mid;// 如果中间元素大于目标值,则在左半部分继续查找 }else if(temp > target){high = mid - 1;// 如果中间元素小于目标值,则在右半部分继续查找}else{low = mid + 1;} }// 如果遍历完整个数组都没有找到目标值,则返回-1return -1;}

4、复杂度分析

  • 时间复杂度:O(mlogn)。对一行使用二分查找的时间复杂度为 O(logn),最多需要进行 m 次二分查找。
  • 空间复杂度:O(1)

5、Z形查找

okok,还有更妙的一个算法呢,本来打算不写了,发现这个算法妙得很啊,Z字形查找。
Z形查找:

  1. 选择起始搜索点:由于矩阵的每一行和每一列都是有序的,从矩阵的右上角(或左下角,取决于搜索策略)开始搜索是一个很好的选择。这里选择右上角是因为它允许我们同时利用行和列的排序特性。
  2. 比较与移动:在搜索过程中,我们不断地将当前元素与目标值进行比较。如果当前元素等于目标值,则搜索成功,返回true。如果当前元素大于目标值,由于列是升序的,我们可以确定目标值不可能在当前列的更上方(即更靠近矩阵顶部的位置),因此我们将搜索范围缩小到当前列的左方一列。相反,如果当前元素小于目标值,由于行是升序的,我们可以确定目标值不可能在当前行的更左方(即更靠近矩阵左侧的位置),因此我们将搜索范围缩小到当前行的下一行。
  3. 迭代搜索:重复上述比较与移动的过程,直到找到目标值或搜索范围为空(即已经遍历到矩阵的左下角或右上角之外的位置)。
public boolean searchMatrix(int[][] matrix, int target) {// 获取矩阵的行数和列数int m = matrix.length, n = matrix[0].length;// 初始化搜索的起始位置,从矩阵的右上角开始  // 选择右上角是因为这样可以同时利用行和列的排序特性来缩小搜索范围int x = 0, y = n - 1;// 当没有越界时,继续搜索while(x < m && y >= 0){// 如果当前元素等于目标值,则搜索成功,返回true if(matrix[x][y] == target){return true;}// 如果当前元素大于目标值,由于列是升序的,所以目标值不可能在当前列的更上方  // 因此,将搜索范围缩小到当前列的左方一列 if(matrix[x][y] > target){y--;// 如果当前元素小于目标值,由于行是升序的,所以目标值不可能在当前行的更左方  // 因此,将搜索范围缩小到当前行的下一行 }else{x++;}}// 如果遍历完所有可能的搜索范围都没有找到目标值,则返回false return false;}

该算法的思想是通过选择合适的起始搜索点,并利用矩阵的行和列都是有序的这一特性,通过不断缩小搜索范围来高效地找到目标值或确定目标值不存在于矩阵中。

复杂度分析——Z查找

  • 时间复杂度:由于每次比较后,搜索范围都会缩小一行或一列,因此该算法的时间复杂度为O(m+n),其中m是矩阵的行数,n是矩阵的列数。这是因为算法最多会遍历矩阵的每一行和每一列各一次。
  • 空间复杂度:该算法的空间复杂度为O(1),因为它只使用了常数个变量来存储搜索过程中的状态(如当前行索引x、当前列索引y以及矩阵的行数m和列数n),而没有使用额外的数据结构来存储搜索过程中的中间结果。

okok,拜拜啦!做完啦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/42026.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构之“栈”(全方位认识)

&#x1f339;个人主页&#x1f339;&#xff1a;喜欢草莓熊的bear &#x1f339;专栏&#x1f339;&#xff1a;数据结构 前言 栈是一种数据结构&#xff0c;具有" 后进先出 "的特点 或者也可见说是 ” 先进后出 “。大家一起加油吧冲冲冲&#xff01;&#xff01; …

玩转springboot之springboot注册servlet

springboot注册servlet 有时候在springboot中依然需要注册servlet&#xff0c;filter&#xff0c;listener&#xff0c;就以servlet为例来进行说明&#xff0c;另外两个也都类似 使用WebServlet注解 在servlet3.0之后&#xff0c;servlet注册支持注解注册&#xff0c;而不需要在…

解决vscode配置C++编译带有中文名称报错问题

在新电脑上安装vscode运行带有中文路径和中文名称的C代码时遇到报错 根据别人的教程将laugh.json文件中"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",改成了"program": "${fileDirname}\\output\\test.exe",&#x…

文化财经macd顶底背离幅图指标公式源码

DIFF:EMA(CLOSE,12) - EMA(CLOSE,26); DEA:EMA(DIFF,9); MACD:2*(DIFF-DEA),COLORSTICK; JC:CROSS(DIFF,DEA); SC:CROSSDOWN(DIFF,DEA); N1:BARSLAST(JC)1; N2:BARSLAST(SC)1; HH:VALUEWHEN(CROSSDOWN(DIFF,DEA),HHV(H,N1));//上次MACD红柱期间合约最大值 HH2:VALUEWHE…

PyQT动态加载ui文件时,如何继承QMainWindow类

主要看mywindow类的写法 不继承时一般这样加载ui文件来创建一个界面&#xff1a; from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QWidget from PyQt5.uic import loadUiclass MyWindow():def __init__(self):self.ui loadUi("your_ui.ui"…

docker部署mycat,连接上面一篇的一主二从mysql

一、docker下载mycat镜像 查看安装结果 这个名称太长&#xff0c;在安装容器时不方便操作&#xff0c;设置标签为mycat docker tag longhronshens/mycat-docker mycat 二、安装容器 先安装一个&#xff0c;主要目的是获得配置文件 docker run -it -d --name mycat -p 8066:…

记一次使用“try-with-resources“的语法导致的BUG

背景描述 最近使用try-catch的时候遇到了一个问题&#xff0c;背景是这样的&#xff1a;当第一次与数据库建立连接以后执行查询完毕并没有手动关闭连接&#xff0c;但是当我第二次获取连接的时候报错了&#xff0c;显示数据库连接失败&#xff0c;连接已经关闭。 org.postgres…

nginx(三)—从Nginx配置熟悉Nginx功能

一、 Nginx配置文件结构 ... #全局块events { #events块... }http #http块 {... #http全局块server #server块{ ... #server全局块location [PATTERN] #location块{...}location [PATTERN] {...}}server{...}... #http全局块 …

Go 语言入门(一)

Go Modules依赖包查找机制 下载的第三方的依赖存储在 $GOPATH/pkg/mod 下go install 生成的可执行文件存储在 $GOPATH/bin下依赖查找顺序&#xff1a; 工作目录$GOPATH/pkg/mod$GOPATH/src 一、Go语言基础 1.标识符与关键字 1.1 命名方式 ​ go变量、常量、自定义类型、包…

Synchronized、volatile与ReentrantLock:Java并发编程中的同步机制比较

在Java并发编程中&#xff0c;确保多个线程安全地访问共享资源是至关重要的一环。Synchronized、volatile与ReentrantLock是三种常用的同步机制&#xff0c;它们各有特点和应用场景。下面从技术难点、面试官关注点以及回答吸引力三个方面详细比较这三种机制。 技术难点 Synch…

怎样把自己电脑ip改成动态ip:步骤与解析

在今天的网络世界中&#xff0c;IP地址是计算机与互联网沟通的桥梁。而动态IP地址&#xff0c;作为其中的一种类型&#xff0c;由于其自动分配和管理的特性&#xff0c;为用户提供了更大的便利性和灵活性。那么&#xff0c;您是否想知道怎样将电脑IP改为动态呢&#xff1f;本文…

【C++PCL】点云处理两组点云的最小距离

作者:迅卓科技 简介:本人从事过多项点云项目,并且负责的项目均已得到好评! 公众号:迅卓科技,一个可以让您可以学习点云的好地方 重点:每个模块都有参数如何调试的讲解,即调试某个参数对结果的影响是什么,大家有问题可以评论哈,如果文章有错误的地方,欢迎来指出错误的…

一级指针 二级指针

目录 一级指针 二级指针 通过二级指针打印原数据 一级指针 一级指针就是存放变量的指针 代码演示&#xff1a; #include<stdio.h> int main() {int a 10;int* pa &a;return 0; } pa就是一级指针变量&#xff0c;是变量就会有地址&#xff0c;因为变量都是在…

非堆成加密是公私钥使用

对称加密学习-CSDN博客 加密算法学习-CSDN博客 非对称加密算法使用一对密钥&#xff0c;包括一个公钥和一个私钥&#xff0c;它们是数学上相关联的&#xff0c;但公钥可以公开分享&#xff0c;而私钥必须保密。以下是使用非对称加密算法的一般步骤&#xff1a; 密钥生成&…

《昇思25天学习打卡营第13天|onereal》

今天学习的内容如下&#xff1a; DCGN生成漫画头像 在下面的教程中&#xff0c;我们将通过示例代码说明DCGAN网络如何设置网络、优化器、如何计算损失函数以及如何初始化模型权重。在本教程中&#xff0c;使用的动漫头像数据集共有70,171张动漫头像图片&#xff0c;图片大小均为…

L1218-L5298清零软件使用图解

清零前请取消打印任务&#xff0c;打印机用USB线接电脑并开启 双击[Resetter.exe]启动软件,点击[Select],选择Port打印机型号&#xff0c;然后点[OK]&#xff0c;如图。 [如果port下拉列表中找不到你的打印机&#xff0c;请更换USB接口&#xff0c;并重新开打印机重试。] 2.…

使用nodejs输出著作权申请所需的word版源码

使用nodejs输出著作权申请所需的word版源码 背景 软件著作权申请需要提供一份80页的word版源代码&#xff0c;如果手工复制源码到word文档中&#xff0c;工作量将无聊到让任何一个DAO人员血压爆表&#xff0c;因此我们不得不编写一个简单的文本处理代码&#xff0c;通过自动方…

【IT领域新生必看】 Java编程中的重载(Overloading):初学者轻松掌握的全方位指南

文章目录 引言什么是方法重载&#xff08;Overloading&#xff09;&#xff1f;方法重载的基本示例 方法重载的规则1. 参数列表必须不同示例&#xff1a; 2. 返回类型可以相同也可以不同示例&#xff1a; 3. 访问修饰符可以相同也可以不同示例&#xff1a; 4. 可以抛出不同的异…

7 系列 FPGA 引脚及封装(参考ug475)

目录 I/O BankPins引脚定义I/O and Multi-Function PinsPower Supply PinsDedicated XADC PinsTransceiver PinsDedicated Configuration PinsTemperature Sensor Pins Device 视图整个 FPGAIOBILOGIC,OLOGIC,IDELAY,ODELAYBUFIO,BUFR,IDELAYCTRLBUFMRCEBRAM,DSPIBUFDS_GTE2CLB…

方法引用详解

什么是方法引用&#xff1f;&#xff1a;针对于函数式接口中的抽象方法 为什么用方法引用&#xff1f;&#xff1a;避免代码的重复&#xff0c;简便书写&#xff0c;提高效率 在使用Lambda表达式的时候&#xff0c;我们实际上传递进去的代码就是一种解决方案&#xff1a;拿参数…