《程序员面试金典(第6版)》面试题 10.09. 排序矩阵查找(观察法,二分法,分治算法入门题目,C++)

news2024/9/22 3:47:21

题目描述

给定M×N矩阵,每一行、每一列都按升序排列,请编写代码找出某元素。

示例:

现有矩阵 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。

  • 给定 target = 20,返回 false。

解题方法与思路

  • 这道题,确实可以算作一道中等题。它一共有三种解决方案,一种方法的时间复杂度都要低于前面一种的时间复杂度。并且,每一种都有它独特的地方在。我想,这就是这道题的魅力所在。

  • 接下来,就让我来为你讲述,这道题的三种方法究竟是哪三种方法。

方法一:顺序查找法

顾名思义,就是顺序查找,暴力破解。我们用两个双层for循环去解决它。

  • 但是,需要注意的是,使用一般的双层for循环,这道题会超时,得写成类似于这样的形式才行
  • for (const auto& row: matrix)
  • 这是因为这样的写法,就不会去复制数组里的元素值,从而节省了一定的时间。

具体的代码如下:

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.empty()) return false;
        for (const auto& row: matrix) {
            for (int element: row) {
                if (element == target) {
                    return true;
                }
            }
        }
        return false;
    }
};

在这里插入图片描述

复杂度分析

时间复杂度:O(mn) 其中m是矩阵的行数,n是矩阵的列数
空间复杂度:O(1)

方法二:二分查找法

  • 由于这个矩阵中的元素是有序的,所以我们可以使用二分查找法来降低时间复杂度。
  • 我们分别对矩阵的每一行使用二分查找,去找目标元素,找到了就返回true,否则就是false
  • 二分查找其实就是设置两个指针left 与 right 分别指向数组的头元素与尾元素。然后使用while循环去遍历这整个数组
  • left 要小于等于 right 。我们找到数组的中间元素mid。 假如mid 等于目标元素,返回true,小于目标元素,left = mid +1,否则就是right = mid -1
  • 最后如果都找不到就返回 false

具体的代码如下

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        for(int i = 0; i < matrix.size(); ++i){
            int left = 0;
            int right = matrix[0].size() - 1;
            while(left <= right){
                int mid = (left + right) / 2;
                if(matrix[i][mid] == target) return true;
                else if(matrix[i][mid] < target) left = mid +1;
                else right = mid - 1;
            }
        }
        return false;
    }
};

在这里插入图片描述

复杂度分析

时间复杂度:O(m * log(n)) 其中m是矩阵的行数,n是矩阵的列数
空间复杂度:O(1)

方法三:基于观察法的查找矩阵算法,Z字查找

  • 我们观察矩阵,发现这个矩阵的横向与纵向的元素其实都是递增的。
  • 根据这个特性,我们可以从矩阵的右上角元素开始遍历。
  • 假如目标元素大于右上角元素,说明这个元素,大于第一行所有元素,下次遍历的时候,就直接少遍历一行,从下一行开始遍历。
  • 假如目标元素小于左上角元素,那就说明,这个元素,直接小于最后一列的所有元素,所以下次就直接少遍历一列。
  • 由此这样遍历,每一次遍历,都能缩小一行或者一列的元素。进一步的缩小了时间复杂度与空间复杂度。

具体的代码如下:

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.empty()) return false;
        int row = 0;
        int col = matrix[0].size() - 1;
        while(row < matrix.size() && col >= 0){
            if(matrix[row][col] > target) --col;
            else if(matrix[row][col] < target) ++row;
            else return true;
        }
        return false;
    }
};

在这里插入图片描述

复杂度分析

时间复杂度:在这个解决方案中,我们从右上角开始搜索,并在每次迭代中排除一行或一列。在最坏的情况下,我们可能需要遍历所有的行和列,因此时间复杂度为 O(M+N),其中 M 是矩阵的行数,N 是矩阵的列数。

空间复杂度:这个算法没有使用额外的数据结构来存储数据,只使用了几个整数变量(如 row 和 col),因此空间复杂度为 O(1)。

这个优化方案相对于二分查找方案,在时间复杂度上有所改进,而空间复杂度保持不变。

总结

  • 这道题用到了二分查找法与观察法来解决矩阵问题,是一道夯实基础的好题。

  • 觉得我写的还行的小伙伴们请给我点一个赞,点一下关注,谢谢!你们的赞与关注就是对我持续输出优质内容的最大鼓励!

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

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

相关文章

wma格式怎么转换mp3,4种方法超快学

其实我们在任何电子设备上所获取的音频文件都具有自己的格式&#xff0c;每种格式又对应着自己的属性特点。比如wma就是一种音质优于MP3的音频格式&#xff0c;虽然很多小伙伴比较青睐于wma所具有的音质效果&#xff0c;但也不得不去考虑因wma自身兼容性而引起很多播放器不能支…

【高危】Apache Solr 代码执行漏洞(MPS-wic0-9hjb)

漏洞描述 Apache Solr 是一款开源的搜索引擎。 在Apache Solr 受影响版本中&#xff0c;由于Solr默认配置下存在服务端请求伪造漏洞&#xff0c;且SolrResourceLoader中实现了java SPI机制。当Solr以SolrCloud模式启动时&#xff0c;攻击者可以通过构造恶意的solrconfig.xml文…

几个最基本软件的环境变量配置

在Windows中配置环境变量位置&#xff1a; 控制面板->系统和安全->系统。可以点击&#xff1a;“此电脑”->“属性”直接进入。 点击“高级系统设置”->【环境变量】。在这里可以看见用户变量和系统变量&#xff0c;如果你这台机器不是你一个人使用设置为用户变量…

接口文档设计避坑指南

我们做后端开发的,经常需要定义接口文档。 最近在做接口文档评审的时候&#xff0c;发现一个小伙伴定义的出参是个枚举值&#xff0c;但是接口文档没有给出对应具体的枚举值。其实&#xff0c;如何写好接口文档&#xff0c;真的很重要。今天田螺哥&#xff0c;给你带来接口文档…

Vue学习笔记(4. 生命周期)

1. 生命周期写法&#xff08;vue2与vue3比对&#xff09; 创建前&#xff1a;vue3 setup, vue2 beforeCreate //组件创建前执行的函数 创建后&#xff1a;vue3 setup, vue2 created //组件创建后执行的函数 挂载前&#xff1a;vue3 onBeforeMount, vue2 beforeMount //挂…

FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization

FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization 论文地址&#xff1a;https://arxiv.org/pdf/2303.14189.pdf 概述 本文提出了一种通用的 CNN 和 Transformer 混合的视觉基础模型 移动设备和 ImageNet 数据集上的精度相同的前提下&#xf…

SpringBoot自动配置原理分析

前言&#xff1a; 虽然工作中一直使用的是自研的一款基于spring的框架&#xff0c;但是随着springboot在各公司的广泛使用&#xff0c;公司的一些新项目也开始逐渐使用springBoot了&#xff0c;那么springBoot的一些特性就要仔细学习一下了。 什么是自动配置&#xff1f; 还记…

【牛客刷题专栏】0x21:JZ20 表示数值的字符串(C语言编程题)

前言 个人推荐在牛客网刷题(点击可以跳转)&#xff0c;它登陆后会保存刷题记录进度&#xff0c;重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏&#xff1a;个人CSDN牛客刷题专栏。 题目来自&#xff1a;牛客/题库 / 在线编程 / 剑指offer&#xff1a; 目录 前言问…

Voice Control for ChatGPT 轻松实现使用语音与ChatGPT进行对话。

缘由 日常生活中&#xff0c;我们与亲人朋友沟通交流一般都是喜欢语音的形式来完成的&#xff0c;毕竟相对于文字来说语音就不会显的那么的苍白无力&#xff0c;同时最大的好处就是能解放我们的双手吧&#xff0c;能更快实现两者间的对话&#xff0c;沟通便更高效了。Voice Co…

【瑞吉外卖】002 -- 后台登录功能开发

本文章为对 黑马程序员Java项目实战《瑞吉外卖》的学习记录 目录 一、需求分析 1、页面原型展示 2、登录页面展示 3、查看登录请求信息 4、数据模型 二、代码开发 1、创建实体类Employee&#xff0c;和employee表进行映射 2、创建包结构&#xff1a;&#xff08;Controller、Se…

基于TCP协议的Socket通信

上节中我们给大家接触了Socket的一些基本概念以及使用方法&#xff0c;相信大家对Socket已经有了初步的掌握。本节我们学习使用Socket来实现大文件的断点续传&#xff01;在这里我们以他人的案例进行讲解&#xff0c;这是别人写好的一个Socket上传大文件的例子&#xff0c;不要…

TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:6~11

原文&#xff1a;Mobile Deep Learning with TensorFlow Lite, ML Kit and Flutter 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的…

MySQL(表的增删改查)

文章目录 0. 前言1. Create1.1 单行数据 全列插入1.2 多行数据 指定列插入1.3 插入否则更新1.4 替换 2. Retrieve2.1 SELECT 列2.1.1 全列查询2.1.2 指定列查询2.1.3 查询字段为表达式2.1.4 为查询结果指定别名2.1.5 结果去重 2.2 WHERE 条件2.2.1 英语不及格的同学及英语成绩…

【消息队列】聊一下Kafka多线程消费实例

Kafka Java Consumer设计原理 目前市面上大多数计算机都采用多核CPU来提升系统的处理性能&#xff0c;但是如果在程序开发层面使用单线程的话&#xff0c;那么必定不能完全发挥出系统的真实性能&#xff0c;而kafka Consumer就是单线程的。而这个只是针对于消费消息这个层面来…

【AI热点技术】ChatGPT开源替代品——LLaMA系列之「羊驼家族」

ChatGPT开源替代品——LLaMA系列之「羊驼家族」 1. Alpaca2. Vicuna3. Koala4. ChatLLaMA5. FreedomGPT6. ColossalChat完整的 ChatGPT 克隆解决方案中英双语训练数据集完整的RLHF管线 相关链接 现在如果问什么最火&#xff0c;很多人第一反应肯定就是ChatGPT。的确&#xff0c…

Redis集群模式下使用config set 命令所有节点都会生效吗?

Redis集群模式下使用config set 命令所有节点都会生效吗? 问题: Redis集群模式下使用config set 命令所有节点都会生效吗? 实践检验真理: 前置准备 Redis版本:5.0.5版本 Redis集群模式:三主三从 操作步骤: 分别连接7001节点与7002节点,准备在7001节点使用”config get”…

交友项目【查询好友动态,查询推荐动态】实现

目录 1&#xff1a;圈子 1.1&#xff1a;查询好友动态 1.1.1&#xff1a;接口分析 1.1.2&#xff1a;流程分析 1.1.2&#xff1a;代码实现 1.2&#xff1a;查询推荐动态 1.2.1&#xff1a;接口分析 1.2.2&#xff1a;流程分析 1.2.3&#xff1a;代码实现 1&#xff1a…

Python教程:如何用PIL将图片转换为ASCII艺术

Python教程&#xff1a;如何用PIL将图片转换为ASCII艺术 ASCII 艺术是一种将图像转换为由字符组成的艺术形式。Python 是一种灵活而强大的编程语言&#xff0c;可以使用它来将图片转换为 ASCII 艺术。本文将介绍如何使用 Python 和 PIL 库来实现这一功能。 文末有完整代码 效…

数学建模第一天:数学建模先导课之MATLAB的入门

目录 一、MATLAB的简介 二、Matlab基础知识 1. 变量 ①命名规则 ②特殊变量名 2、数学符号与函数调用 ①符号 ②数学函数 ③自定义函数 三、数组与矩阵 1、数组 ①创建数组 ②访问数组元素 ③数组运算 2、矩阵 ①定义 ②特殊矩阵 ③矩阵运算 四、控制流 …

若依项目springcloud启动

若依项目springcloud启动 参考&#xff1a;http://doc.ruoyi.vip/ruoyi-cloud/document/hjbs.html 1、概述 1.1、学习前提 熟练使用springboot相关技术了解springcloud相关技术电脑配置可以支持 1.2、需要的配置 JDK > 1.8 (推荐1.8版本) Mysql > 5.7.0 (推荐5.7版…