面试经典150题——两数之和

"Success is not the key to happiness. Happiness is the key to success. If you love what you are doing, you will be successful."

- Albert Schweitzer

aerial view of village on mountain cliff during orange sunset

1. 题目描述

image-20240223074551865

2.  题目分析与解析

2.1 思路一——暴力求解

暴力求解是比较干脆果断的一种解决问题的方式,本质上就可以被描述为一个一个找。对于这个题目,暴力求解思路很简单:

  1. 外层遍历数组 nums的每一个元素A

  2. 内层遍历数组 nums该元素后面的元素(前面的无需遍历是因为前面的元素作为A时已经判定过了)

  3. 将这两个数进行求和,判断是否能够等于target

但是这种求解方法时间复杂度很显而易见时O(N^2),因此我们想一想有什么其它的解决思路。

2.2 思路二——存储下标排序后匹配

不知道大家之前有没有做过关于判断一个数组种有没有两数之和等于target的题目,就是这个题目:

两数之和 II - 输入有序数组

我的解析文章链接为:

面试经典150题——两数之和 II - 输入有序数组

在这篇文章种我讲的很详细,大家先看一下上面这篇文章。但它题目中给的是有序数组,这里我们得到的是无序数组,那么我们是不是就可以稍微进行处理,变成有序数组,然后找到两个数之和等于target的两个元素,找到他们的原始下标返回。

注意:这里是原始下标

因此我们是不是就先需要使用一个结构存储每个元素的原始下标,然后再按照上述思路进行处理,就可以在O(N^2)时间复杂度内求解。

代码思路

  1. 使用一个映射存储原始元素及其下标

  2. 通过双指针方式,从头尾遍历,具体图解见上面链接提到的文章,讲的很详细

  3. 找到两个指针指到的元素等于target,根据原始元素及其下标映射找到他们的原始下标并返回

2.3 思路三——存储下标直接寻找匹配项

现在我们再来想一想,既然我需要求出两个数字之和等于target,那么我如果确定了一个加数,被加数是不是也能确定?

因为被加数就等于target减去加数。因此我是不是就可以先从头到尾遍历一次数组,将每一个元素及其下标先存储起来,然后我再看每一个元素的被加数?如果能够匹配,就把这两个元素的下标返回。

但是考虑一下对于数组:【1,3,5,5,6】,如果我的target=10,那么两个5怎么办?

因此我们hashmap的值应该是一个list,来存储相同大小元素的下标。如下图:

image-20240223110452729

代码思路

  1. 初始化一个hashMap,结构为:Map<Integer, List<Integer>> 用来存储数组 nums的元素和下标

  2. 遍历数组 nums的每一个元素

  3. 如果hashMap中包含target-nums[i],返回target-nums[i]和nums[i]的下标

    • 在这里需要判读这两个数是否相等,如果两个元素相等,那么返回两个元素的下标就是如上图所示

    • 如果两个元素不相等那么就返回对应的value列表的第一个元素

2.4 思路四——直接匹配

现在我们思考一下,如果我们需要找到target的两个加数,那么这两个加数肯定有出现的先后次序对不对?他们肯定不可能拥有相同的下标,所以对于两个加数A,B,要么A的下标大,要么B的下标大。

其次,如果我们走过了较小下标的那个加数,假设我们将它存储了起来,那么是不是走到较大下标加数时,只需要判断之前有没有走过某一个加数能够匹配,实现 A+B=target ?

而这个判断过程并不需要再回过头去看之前走过的数字,因为我们需要的匹配是一个很精准的匹配,就是找 target-B,也就是找一个数。如果我们对于已经走过的每一个数都进行了hash,那么是不是就可以再O(1)时间找到该数?

所以可以有如下:

代码思路:

  1. 初始化一个hashMap,键为数值,value为位置

  2. 遍历nums的每一个数,尝试找到与之匹配的target-B是否在hashMap中存在

    • 如果存在,就将这两个下标返回

    • 如果不存在,就先将该元素及其下标放入hashMap(假设存在解且它是加数,那么他后面肯定有一个被加数)

  3. 都找不到返回null

3. 代码实现

3.1 思路一

image-20240223075330462

image-20240223075228798

3.2 思路二

image-20240223082841497

image-20240223082651115

3.3 思路三

image-20240223111408991

image-20240223111253532

3.4 思路四

image-20240223114627001

image-20240223114555045

4. 相关复杂度分析

​解法一(暴力枚举)

  • 时间复杂度: (O(n^2))。因为这个解法涉及到一个双重循环遍历所有元素的组合,对于每对元素组合,它检查它们的和是否等于目标值。

  • 空间复杂度: (O(1))。这个方法只使用了固定的额外空间(用于存储结果和循环变量)。

解法二(排序后使用双指针)

  • 时间复杂度: (O(n log n))。主要的时间开销来自于排序操作,而双指针遍历的时间复杂度为 (O(n))。

  • 空间复杂度: (O(n))。这个方法需要额外的空间来存储元素到其索引列表的映射,以及处理可能存在的重复元素。

解法三(使用哈希表存储元素和索引,改进的遍历)

  • 时间复杂度: (O(n))。每个元素被遍历两次,并且哈希表的查找操作时间复杂度为 (O(1))。因此,总的时间复杂度是线性的。

  • 空间复杂度: (O(n))。需要额外的空间来存储元素到其索引列表的映射,用于处理重复元素和实现快速查找。

解法四(使用哈希表存储元素和索引,即时检查)

  • 时间复杂度: (O(n))。与解法三相似,这个方法通过遍历数组一次,并在遍历过程中使用哈希表来检查是否存在满足条件的元素对,从而达到线性时间复杂度。

  • 空间复杂度: (O(n))。这个方法同样需要额外的空间来存储元素到其索引的映射,其空间复杂度也是基于输入数组的大小。

综上所述,解法一是时间复杂度最高的方法,不适合大数据集。解法二和解法二修改版虽然在时间上有所改进,但仍受到排序步骤的限制。解法三和解法四提供了最优的时间复杂度解决方案,且解法四在实际应用中更为直观和高效,因为它无需事先处理所有元素,而是在遍历过程中即时查找并返回结果。

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

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

相关文章

Selenium浏览器自动化测试框架详解

selenium简介 介绍 Selenium [1] 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。支持的浏览器包括IE&#xff08;7, 8, 9, 10, 11&#xff09;&#xff0c;Mozilla Firefox&#xff0c;Safari&#xff0c;Google C…

构建生物医学知识图谱from zero to hero (4):通过Neo4j构建知识图谱

图数据库是一种专门用于存储图形数据的 NoSQL 数据库。与传统的关系型数据库和其他 NoSQL 数据库不同,图数据库利用图形数据模型来存储和管理数据。图形数据模型由节点和边组成,节点代表实体,边代表实体之间的关系。例如,在社交网络中,用户可以表示为节点,朋友关系可以表…

【Spring】 AOP面向切面编程

文章目录 AOP是什么&#xff1f;一、AOP术语名词介绍二、Spring AOP框架介绍和关系梳理三、Spring AOP基于注解方式实现和细节3.1 Spring AOP底层技术组成3.2 初步实现3.3 获取通知细节信息3.4 切点表达式语法3.5 重用&#xff08;提取&#xff09;切点表达式3.6 环绕通知3.7 切…

时间获取、文件属性获取 2月20日学习笔记

执行两次代码&#xff0c;打印出两次执行过程中新增的文件及删除的文件 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <dirent.h>#def…

多人协作记账账本小程序开源版开发

多人协作记账账本小程序开源版开发 支持多人协作的记账本小程序&#xff0c;可用于家庭&#xff0c;团队&#xff0c;组织以及个人的日常收支情况记录&#xff0c;支持周月年度统计 便捷记账 便捷的记账方式&#xff0c;支持多种记账类型&#xff0c;快捷切换账本等 多账本 支…

发布订阅模式:观察者模式的一种变体

发布-订阅模型&#xff08;Publish-Subscribe Model&#xff09;的底层机制通常基于观察者模式。 发布-订阅模型是观察者模式的一种变体。 在观察者模式中&#xff0c;主题&#xff08;或被观察者&#xff09;维护了一组观察者&#xff0c;当主题的状态发生变化时&#xff0c…

TypeScript 学习笔记

主要内容参考菜鸟教程&#xff0c;结合了自己学习过程中的一些拓展 TypeScript 基础语法 | 菜鸟教程 1.1 环境配置 1.1.1 安装ts npm install -g typescript 1.2.1 编写demo var message:string "Hello World" console.log(message) 1.3.1 运行 1.3.1.1 命令行…

刘雯井柏然植物园漫步,情侣裙超养眼,甜蜜穿搭亮了。

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 刘雯井柏然漫步永州植物园&#xff0c;情侣裙惊艳亮相&#x…

稀疏计算、彩票假说、MoE、SparseGPT

稀疏计算可能是未来10年内最有潜力的深度学习方向之一&#xff0c;稀疏计算模拟了对人脑的观察&#xff0c;人脑在处理信息的时候只有少数神经元在活动&#xff0c;多数神经元是不工作的。而稀疏计算的基本思想是&#xff1a;在计算过程中&#xff0c;将一些不重要的参数设置为…

306_C++_QT_创建多个tag页面,使用QMdiArea容器控件,每个页面都是一个新的表格[或者其他]页面

程序目的是可以打开多个styles文件(int后缀文件),且是tag样式的(就是可以切多个页面出来,并且能够单独关闭);其中读取ini文件,将其插入到表格中的操作,也是比较复杂的,因为需要保持RGB字符串和前面的说明字符串对齐 ini文件举例: [MainMenu] Foreground\Selected=&…

计算机网络Day1--计算机网络体系

1.三网合一 电信网络、广播电视网络、计算机网络&#xff08;最基础最重要发展最快&#xff09; 2.Internet 名为国际互联网、因特网&#xff0c;指当前全球最大的、开放的、由众多网络相互连接而成的特定互连网&#xff0c;采用TCP/IP 协议族作为通信的规则&#xff0c;前…

【Flink】FlinkSQL读取hive数据(批量)

一、简介: Hive在整个数仓中扮演了非常重要的一环,我们可以使用FlinkSQL实现对hive数据的读取,方便后续的操作,本次例子为Flink1.13.6版本 二、依赖jar包准备: 官网地址如下: Overview | Apache Flink 1、我们需要准备相关的jar包到Flink安装目录的lib目录下,我们需…

【ArcGIS微课1000例】0105:三维模型转体模型(导入sketchup转多面体为例)

文章目录 一、实验概述二、三维模型转多面体三、加载多面体数据四、注意事项一、实验概述 ArcGIS可以借助【导入3D文件】工具支持主流的三维模型导入。支持 3D Studio Max (.3ds)、VRML and GeoVRML 2.0 (.wrl)、SketchUp 6.0 (.skp)、OpenFlight 15.8 (.flt)、Collaborative …

通俗易懂理解CA(Coordinate Attention)

一、参考资料 github代码&#xff1a;CoordAttention Coordinate Attention 二、相关介绍 通道注意力与空间注意力 关于通道注意力和空间注意力的详细介绍&#xff0c;请参考另一篇博客&#xff1a;通俗易懂理解通道注意力机制(CAM)与空间注意力机制(SAM) 注意力机制是用…

分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进的麻雀搜索算法优化最小二乘支持向量机故障诊断分类预测

分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进的麻雀搜索算法优化最小二乘支持向量机故障诊断分类预测 目录 分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进的麻雀搜索算法优化最小二乘支持向量机故障诊断分类预测分类效果基本描述程序设计参考资…

桥接模式:解耦抽象与实现,实现灵活多变的扩展结构

文章目录 一、引言二、应用场景与技术背景三、模式定义与实现四、实例详解五、优缺点分析总结&#xff1a; 一、引言 ​ 桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与它的实现部分分离&#xff0c;使它们可以独立变化。这种模式通过创建一个抽象层和实现层的结构&…

TiDB离线部署、Tiup部署TiDB

先做tidb准备工作&#xff1a; 部署 TiDB 前的环境检查操作&#xff1a;TiDB 环境与系统配置检查 | PingCAP 文档中心 1.查看数据盘 fdisk -l &#xff08;2,3&#xff09;本人的分区已经是 ext4 文件系统不用分区&#xff0c;具体官方文档的分区&#xff1a; 4.查看数据盘…

C#_扩展方法

简述&#xff1a; 扩展方法所属类必需是静态类&#xff08;类名依据规范通常为XXXExtension&#xff0c;XXX为被扩展类&#xff09;扩展方法必需是公有的静态方法扩展方法的首个参数由this修饰&#xff0c;参数类型为被扩展类型 示例&#xff1a; static class DoubleExtens…

IDEA 2023.2 配置 JavaWeb 工程

目录 1 不使用 Maven 创建 JavaWeb 工程 1.1 新建一个工程 1.2 配置 Tomcat 1.3 配置模块 Web 2 使用 Maven 配置 JavaWeb 工程 2.1 新建一个 Maven 工程 2.2 配置 Tomcat &#x1f4a5;提示&#xff1a;IDEA 只有专业版才能配置 JavaWeb 工程&#xff0c;若是社区版&am…

Bert基础(二)--多头注意力

多头注意力 顾名思义&#xff0c;多头注意力是指我们可以使用多个注意力头&#xff0c;而不是只用一个。也就是说&#xff0c;我们可以应用在上篇中学习的计算注意力矩阵Z的方法&#xff0c;来求得多个注意力矩阵。让我们通过一个例子来理解多头注意力层的作用。以All is well…