二维数组中的查找(两种解法,各有千秋)

news2024/11/16 3:34:51

凡事都有可能,永远别说永远。——《放牛班的春天》

今天一题为再一个行列都有序的二维数组中寻找一个目标值,我们第一时间想到的可能是很暴力的解法,例如从头到尾进行遍历,这样能做出来,但是借用武忠祥老师的一句话:这样做你就慢了,没效率。

本文章会从复杂度的角度来分析一个算法,循序渐进的提升这个算法的优秀程度。最终优化为最优算法。

一.题目及示例

在一个二维数组array中(每个一维数组的长度相同), 每一行都按照 从左到右递增的顺序排序, 每一列都按照 从上到下递增的顺序排序。请 完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。

下面给出示例:

解法一(暴力解法):

拿到这道题目,第一种方法不难想到,就是对整个数组进行遍历,每一个元素都扫一遍。这种解法比较暴躁,很暴力,给它一个外号,叫"暴力解法"。

具体代码实现如下:

bool Find(int target, vector<vector<int> > array) {
        // 利用C++的auto进行遍历
        for(auto x:array) {
            for(auto y:x){
                // 如果存在,直接返回true
                if(y==target){
                    return true;
                }
            }
        }
        return false;

ps:这里的for循环不是普通的for循环,这是C++新定义的for循环,具体使用可以去看我下一篇博客。

我把他称之为升级版for循环。

复杂度分析:

  • 需要对二维数组的每个元素进行遍历,时间复杂度为O(n^2)

  • 存储一个二维数组,空间复杂度为O(1)

解法二(双指针法)

由于矩阵行列都是严格递增的,此矩阵为杨氏矩阵,故也称杨氏矩阵法。

  • 如果这个是一个没有任何规律的数组,那么可能就只有那种写法了,但是这个题目(红字)告诉我们这个数字从上到下,从左到右都是递增的,所以我们可以从这个方向入手。我们发现,我们找一个数,最快的办法无非就是利用二分进行查找,但是我们发现这个题目是一个二维单调的。所以我们要想办法找到一个方法可以在我们判断到数字小了或者大了的时候可以进行一个范围的缩小。这样的话,我们就可以定义两个指针,放到右上角或者左下角。这里我放到右上角进行讨论。
    初始的时候,我们的两个x和y的指针放到了右上角。这样的话我们可以与目标数进行比较,如果发现这个数比目标数小了,我们就把y指针往下进行移动,y指针自增。如果发现这个数比目标数大了,我们就可以往左边方向进行移动,x指针自减。

具体代码实现如下:

(右上角代码)

 bool Find(int target, vector<vector<int> > array) {
        int len1=array.size();  // 计算行数
        int len2=array[0].size();  //计算列数
        int posx=0,posy=len2-1; //定义两个指针,分别指向x和y的坐标
        while(posx<len1&&posy>=0){
            // 当前的数字比目标数字大,x指针左移
            if(array[posx][posy]>target){
                posy--;
            // 当前的数字比目标数字小,y指针往下移动
            }else if(array[posx][posy]<target){
               posx++;
            }else{
                return true;
            }
        }
        return false;
    }

(左下角代码)

bool Find(int target, vector<vector<int> > array) {
        int len1=array.size(); // 行数
        int len2=array[0].size();  //列数
        int posx=len1-1,posy=0; // 定义两个指针,分别表示x和y的指针
        while(posx>=0&&posy<len2){
            // 当前的数字比目标数字大,x指针往上移动
            if(array[posx][posy]>target){
                posx--;
            // 当前的数字比目标数字小,y指针往右方向移动
            }else if(array[posx][posy]<target){
               posy++;
            }else{
                return true;
            }
        }
        return false;
    }

复杂度分析:

由于x和y分别只能往一个方向进行移动。

  • 右上角版,最有最多只会遍历一行和一列的长度,时间复杂度为O(n+m)

  • 二维数组存储所有的元素,空间的复杂度为O(1)

我们做个总结,相对于第一题,第二题的时间复杂度从n^2到m+n得到提升,提升的原因就是很好的利用升序这个特点来优化。

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

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

相关文章

15-基础加强-1-类加载器反射

文章目录1.类加载器1.1类加载器【理解】1.2类加载的过程【理解】1.3类加载的分类【理解】1.4双亲委派模型【理解】1.5ClassLoader 中的两个方法【应用】2.反射2.1反射的概述【理解】2.2获取Class类对象的三种方式【应用】 第1步&#xff1a;获取类的Class对象2.3反射获取构造方…

【FiddlerScript】利用Fiddler中的FiddlerScript解除4399小游戏的防沉迷

本文仅供技术探讨&#xff0c;切勿用于非法用途案例网站:小游戏,4399小游戏,小游戏大全,双人小游戏大全 - www.4399.com准备的工具:配置好的Fiddler一个Fiddler官方英文版配置教程:https://www.bilibili.com/video/BV1rP4y1t7ZLFiddler中文版配重教程:https://www.bilibili.com…

懒加载以及预加载相关概念

⼆、懒加载 1. 懒加载的概念 懒加载也叫做延迟加载、按需加载&#xff0c;指的是在⻓⽹⻚中延迟加载图⽚数据&#xff0c;是⼀种较好的⽹⻚性能优化 的⽅式。 在⽐较⻓的⽹⻚或应⽤中&#xff0c;如果图⽚很多&#xff0c;所有的图⽚都被加载出来&#xff0c;⽽⽤户只能看到…

创建vue项目

前提安装node.js 安装vue脚手架 命令: npm install -g vue/cli 安装完成后查看下版本 vue --version 开始创建vue项目,可以用cmd终端也可以用pow(Windows PowerShell) 搜索输入pow以管理员运行 找一个项目存放位置 pow进入该目录 创建项目命令 如果创建项目时候报错 输入…

解读|奔驰财报展现强大现金实力,2年内回购价值40亿欧元股票

2月17日&#xff0c;梅赛德斯-奔驰集团股份公司&#xff08;股票代码&#xff1a;MBG&#xff09;发布了拆分后的第一个财年业绩报告&#xff0c;2022年&#xff0c;该集团实现营业总收入1500.17亿欧元&#xff0c;同比上年增长35%&#xff1b;实现税前利润为204.58亿欧元&…

【基础】Flink -- ProcessFunction

Flink -- ProcessFunction处理函数概述处理函数基本处理函数 ProcessFunction按键分区处理函数 KeyedProcessFunction定时器与定时服务基于处理时间的分区处理函数基于事件时间的分区处理函数窗口处理函数 ProcessWindowFunction应用案例 -- Top N处理函数概述 为了使代码拥有…

基于Springbot+微信小程序的购药平台的设计与实现

基于Springbot微信小程序的购药平台的设计与实现 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、…

Jackson 序列化:Cannot deserialize value of type `java.time.LocalDateTime`

问题描述 使用 jackson 反序列化异常如下&#xff1a; Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.time.LocalDateTime from String “2023-02-13 19:43:01”: Failed to deserialize java.time.LocalDat…

MySQL的四种事务隔离级别

目录一、事务的基本要素&#xff08;ACID&#xff09;1、原子性&#xff08;Atomicity&#xff09;&#xff1a;2、一致性&#xff08;Consistency&#xff09;&#xff1a;3、隔离性&#xff08;Isolation&#xff09;&#xff1a;4、持久性&#xff08;Durability&#xff09…

使用canvas给上传的整张图片添加平铺的水印

写在开头 哈喽&#xff0c;各位倔友们又见面了&#xff0c;本章我们继续来分享一个实用小技巧&#xff0c;给图片加水印功能&#xff0c;水印功能的目的是为了保护网站或作者版权&#xff0c;防止内容被别人利用或白嫖。 但是网络中&#xff0c;是没有绝对安全的&#xff0c;…

iOS接入Google登录

1.在Google Cloud后台配置客户端ID 首先要在 Google Cloud 中创建一个项目。新创建的Project需要先配置同意屏幕。一共有4步骤需要配置。 1.OAuth 同意屏幕 User Type选择"外部"进行创建。填写必必要的信息&#xff0c;应用名称、用户支持电子邮件地址、开发者电子邮…

chatGPT是什么?chatGPT运用场景有哪些?

大家好&#xff0c;小编来为大家解答以下问题 chatGPT是什么&#xff1f;&#xff0c;chatGPT概念股有哪些&#xff1f;一个有趣的事情&#xff0c;一个有趣的事情&#xff0c;现在让我们一起来看看吧&#xff01; 1、chatpgt是什么 ChatGPT是OpenAI开发的大型预训练语言模型。…

yolov5 onnx 前后处理+运行推理(暂记)

代码在这个基础上改的&#xff0c;虽然跑通了&#xff0c;还是很混乱&#xff0c;这里先简单记录一下处理的流程&#xff1a; yolov5 环境设置yolov5 网络结构ONNX yolov5导出 convert error --grid番外&#xff1a;onnx直接操作番外&#xff1a;yolov5的重新训练 result 0 -…

[安装之4] 联想ThinkPad 加装固态硬盘教程

方案&#xff1a;保留原有的机械硬盘&#xff0c;再加装一个固态硬盘作为系统盘。由于X250没有光驱&#xff0c;这样就无法使用第二个2.5寸的硬盘。还好&#xff0c;X250留有一个M.2接口&#xff0c;这样&#xff0c;就可以使用NGFF M.2接口的固态硬盘。不过&#xff0c;这种接…

短视频时代是靠什么赚钱的,介绍常见的5种方式,简单明了

目前&#xff0c;短视频越来越火热&#xff0c;大家都知道做短视频可以赚钱&#xff0c;那么究竟是靠什么赚钱的&#xff0c;又有几个人知道呢&#xff1f;短视频创业有个人、有团队&#xff0c;怎么实现团队的生存和发展。 常见的几种变现方式有&#xff1a; 1、平台分成 各…

C语言中用rand()函数产生一随机数

在C语言中如何产生一个随机数呢&#xff1f;用rand()函数。 rand()函数在头文件&#xff1a;#include <stdio.h>中&#xff0c;函数原型&#xff1a;int rand(void);。rand()会返回一个范围在0到RAND_MAX&#xff08;32767&#xff09;之间的随机数&#xff08;整数&…

Pytorch 基础之张量数据类型

学习之前&#xff1a;先了解 Tensor&#xff08;张量&#xff09; 官方文档的解释是&#xff1a; 张量如同数组和矩阵一样, 是一种特殊的数据结构。在PyTorch中, 神经网络的输入、输出以及网络的参数等数据, 都是使用张量来进行描述。 说白了就是一种数据结构 基本数据类型…

Python可以解码吗,解码打码是如何实现的

前言 咳咳&#xff0c;进来的铁汁都是抱着学习的心态进来看的吧&#xff0c;咱今天不讲解解码&#xff0c;咱来说说python如何来实现打码功能~ 这一个个进来的 都是标题党吧哈哈哈 有兴趣的可以继续看看哦 最近重温了一档综艺节目 至于叫什么 这里就不细说了 老是看着看着就…

【QT 5 相关实验-示波器-学习笔记-示波器组件练习与使用总结】

【QT 5 相关实验-示波器-学习笔记-示波器组件练习与使用总结】1、概述2、实验环境3、参考资料-致谢4、自我提升实验效果视频演示5、代码练习-学习后拆解-实验步骤&#xff08;1&#xff09;头文件部分-"mwaveview.h"&#xff08;2&#xff09;cpp文件部分-"mwav…

UDP数据报套接字编程

DatagramSocket API DatagramSocket 是UDP Socket&#xff0c;用于发送和接收UDP数据报。 DatagramSocket 构造方法&#xff1a; DatagramSocket 方法&#xff1a; DatagramPacket API DatagramPacket是UDP Socket发送和接收的数据报。 DatagramPacket 构造方法&#xff…