面试经典150题——存在重复元素 II

​"The harder you work for something, the greater you'll feel when you achieve it." - Unknown

black laptop computer beside black ceramic mug

1. 题目描述

image-20240224190929331

2.  题目分析与解析

2.1 思路一——暴力求解

该思路很简单,就是暴力的查找每一个元素,查看是否满足题目要求,满足就返回true,不满足就返回false。

代码思路:

  1. 一层for循环遍历每个 abs(i - j) <= k中的被减数

  2. 二层for循环遍历每个 abs(i - j) <= k中的减数

  3. 判定是否满足条件

效果果然如预期:

image-20240225080149219

2.2 思路二——哈希表

对于这种题目,因为题目要求 abs(i - j) <= k,它的前提是不同的索引 ij ,满足 nums[i] == nums[j]。那么我们是不是就可以先把那些相同值的组存储起来,然后再寻找这些相同值的组中满足abs(i - j) <= k的进行计算?

如何存储相同值的组?

可以使用一个hashMap,键为每一个数组,值为其对应出现的下标的集合。

然后就可以通过遍历hashMap的每一个键,寻找其对应的值的元素个数大于等于两个的部分,然后再对这个部分排序(也就是下标进行排序),然后两两相减查看是否满足条件abs(i - j) <= k

代码思路:

  1. 定义一个hashMap,键位数组所有不相同的元素,值为其出现下标的集合

  2. 遍历hashMap的每一个键,寻找其对应的值的元素个数大于等于两个的部分

  3. 对该部分先进行排序,然后两两相减查看是否满足条件abs(i - j) <= k

之所以只需要两两相减,是因为我们需要找到的是abs(i - j)的最小值,因为如果最小值都不能满足 <= k,那么其它的肯定也不能满足。而最小值肯定就在排序后的两两之间,因为如下:

image-20240225082705414

假如键位 6,对应出现的下标为 {1,3,4,5}那么肯定 abs(i - j)的最小值出现在 {3 - 1,4 - 3,5 - 4}其中。(代码见后3.2)

但是这样写出的代码发现并不是很能打,因为我们相当于遍历了两次所有元素,能否只遍历一次呢?

我们先来思考一下上面遍历两次是哪两次:

  1. 初始化hashMap

  2. 遍历hashMap

因为我们需要的是判断相同元素的下标相减的绝对值是否<=k,那么我们是不是可以在初始化hashMap的时候,就对每一个hashMap的值进行判断:

  • 如果当前hashMap包含了该key,那么我们就进行判定是否满足abs(i - j) <= k

  • 如果当前hashMap不包含该key,那就先把它加入hashMap

这样做的正确性是因为对于hashMap包含了该key的情况,说明该元素是第二次出现了,只需要将这两个元素的下标相减即可,并且对于hashMap的value我们也不需要存储所有相同元素的下标。这是因为记住我们创建这个hashMap的目的是什么,就是寻找最小的 abs(i - j),那么我们就可以通过定义一个变量,保存最小值,不断更新直到满足 <=k即可。

而hashMap的value,就可以存储上一次出现该元素的下标,这样在下一次遇到相同元素,离他最近的肯定是上一个相同元素的位置:

image-20240225084552535

比如上图对于元素5,当遍历到下标2时,最小abs值是2,因为此时走过的元素中离下标2最近且元素值相等的 2 - 0 = 2 此时如下:

image-20240225085920726

当继续遍历到下标3的时候,最小abs值就可以被更新为1:

image-20240225090052865

所以按照如上思路我们就可以将代码进行优化:

优化代码思路:

  1. 初始化一个hashMap,key为不同元素,value为元素的最近一次遍历的下标

  2. 初始化一个最小值

  3. 遍历nums

    • 如果indexMap中包含nums[i],计算i和indexMap.get(nums[i])的差值并更新min

    • 将当前值存入hashMap

    • 如果min小于等于k,返回true

2.3 思路三——滑动窗口

因为我们要得到的结果只是一个布尔值,也就是真或者假,其它任何信息我们都不需要知道,只需要知道是否存在两个相同元素的下标之差的绝对值 <=k

既然是下标之差的绝对值 <=k,那么是不是也就意味着在k+1(因为是小于等于,有等于情况所以需要+1)个相邻元素范围内,需要找到两个相同值的元素?只要找到了,那就说明存在可行解,就可以返回true,否则就返回false。比如如下对于:

image-20240225092408833

image-20240225094926666

如上图所示,红色框就是一次次的判定k+1个相邻元素范围内,能否找到两个相同值的元素,这样不断判定直到结尾:

image-20240225094950509

发现都没有满足那就返回false。

所以我们现在来思考如何判定k+1个相邻元素范围内,能否找到两个相同值的元素?

那我们还是可以借鉴前面的思想,就是用一个hashSet存储k+1个相邻元素的值作为键,不断去判断下一个遍历的值是否在这个红色框中,

  • 如果当前元素下标小于等于k说明,判定该元素是否在框内,如果不在就向框中加入该元素,在就返回true(这是因为在初始化窗口的时候,窗口大小为0)

  • 如果发现当前元素下标大于k了,也就是刚开始位k+1的时候,需要移除窗口最左边的元素,因为此时窗口大小要保持k+1

  • 如果此时hashSet中包含了当前元素nums[i],返回true

  • 如果遍历到了结尾还是没有返回true,就说明不存在解返回false

3. 代码实现

3.1 思路一——暴力求解

image-20240225090515554

3.2 思路二——哈希表

image-20240225083353452

image-20240225083242131

经过优化以后:

image-20240225090449651

image-20240225090425341

3.3思路三——滑动窗口

image-20240225094405228

image-20240225094352010

4. 相关复杂度分析

1. 暴力求解方法 (containsNearbyDuplicate)
  • 时间复杂度: O(n^2) - 这是因为对于数组中的每个元素,代码都进行了一个内部循环来比较所有其他元素。对于长度为n的数组,这就导致了n*(n-1)/2次比较。

  • 空间复杂度: O(1) - 由于不需要额外存储空间,除了输入数组和几个变量外,这个方法不占用额外的空间。

2.1 哈希表方法 (containsNearbyDuplicate2)
  • 时间复杂度: O(n log n) - 这个复杂度主要来自于为每个元素的索引列表进行排序的需求。在最坏的情况下,如果所有元素都相同,则每个元素都会被添加到同一个列表中,对这个列表排序的时间复杂度为O(n log n)。

  • 空间复杂度: O(n) - 在最坏的情况下,如果所有的元素都不同,则HashMap将会存储n个键值对,每个键对应一个只含有一个元素的列表。

2.2 哈希表方法优化 (containsNearbyDuplicate2_modify)
  • 时间复杂度: O(n) - 对于每个元素,只需要O(1)的时间来更新哈希表,并检查当前元素与之前出现的元素之间的距离。

  • 空间复杂度: O(n) - 哈希表在最坏的情况下可能需要存储n个键值对,即数组中的每个元素都不相同。

3. 滑动窗口方法 (containsNearbyDuplicate3)
  • 时间复杂度: O(n) - 数组中的每个元素都被访问一次。对于每个元素的访问,检查元素是否在HashSet中以及添加和删除操作都可以在O(1)时间内完成。

  • 空间复杂度: O(min(n, k)) - 滑动窗口方法中,HashSet的大小由窗口的最大大小k决定,但不会超过n(数组的长度)。在最坏的情况下,如果k大于或等于n,那么空间复杂度将是O(n);如果k小于n,空间复杂度是O(k)。

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

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

相关文章

Darkhole 2

kali:192.168.223.128 靶机:192.168.223.152 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -sV -p- -A 192.168.223.152 开启了22 80 端口 web 进入登录界面发现没有注册按钮了 扫一下目录 gobuster dir -u http://192.168.223.152 -x html,txt,php,bak,zip,git --wor…

单片机精进之路-5矩阵键盘扫描

如下图&#xff0c;先在p3口输出0xfe&#xff0c;再读取p3口的电平&#xff0c;如果没有按键按下&#xff0c;temp & 0xf0还是0xf0&#xff0c;如果又第一个键按下&#xff0c;temp & 0xf0还是0xee&#xff0c;其他按键由此类推可得。 //4*4键盘检测程序,按下键后相应…

Linux的文件操作,重拳出击( ̄︶ ̄)

Linux的文件操作 学习Linux的文件操作&#xff0c;一般需要知道一个文件如果你想要操作他&#xff0c;必须知道你对这个文件有什么操作的权限或者修改你自己对文件操作的权限。必须要知道文件有三种权限 r&#xff1a;可读 w&#xff1a;可写 x&#xff1a;可执行 在打开Linux…

✅鉴权—cookie、session、token、jwt、单点登录

基于 HTTP 的前端鉴权背景cookie 为什么是最方便的存储方案&#xff0c;有哪些操作 cookie 的方式session 方案是如何实现的&#xff0c;存在哪些问题token 是如何实现的&#xff0c;如何进行编码和防篡改&#xff1f;jwt 是做什么的&#xff1f;refresh token 的实现和意义ses…

《C++面向对象程序设计》✍学习笔记

C的学习重点 C 这块&#xff0c;重点需要学习的就是一些关键字、面向对象以及 STL 容器的知识&#xff0c;特别是 STL&#xff0c;还得研究下他们的一些源码&#xff0c;下面是一些比较重要的知识&#xff1a; 指针与引用的区别&#xff0c;C 与 C 的区别&#xff0c;struct 与…

网络技术ensp 一个简单的交换机配置案例

由于工作调岗&#xff0c;转战网络运维了&#xff0c;第一次网络笔记 1.&#xff0c;目的&#xff1a;2台主机相互可以ping通&#xff0c;并且可以ping通网关地址&#xff0c;设备&#xff1a;2台主机&#xff0c;2台交换机 2网络拓扑图如下 3.主机pc1的配置信息 ip&#xff…

Xcode与Swift开发小记

文章目录 引子Xcode工程结构核心概念Swift语法速记(TODO)小技巧单元测试中使用awaitSwiftUI中使用ListView中取数据 常见问题Xcode添加package时连接github超时Xcode无法修改快捷键&#xff0c;一闪而过 引子 鉴于React Native目前版本在iOS上开发遇到诸多问题&#xff0c;本以…

前端取图片相同颜色作为遮罩或者背景

需求 遮罩层取图片相同/相似的颜色作为遮罩 效果 做法 npm库 grade.js 所提供图像中前 2 个主色生成的互补渐变https://github.com/benhowdle89/grade COLOR THIEF 只需使用Javascript即可从图像中获取调色板。 https://github.com/lokesh/color-thief https://lokeshd…

AIGC专栏9——Scalable Diffusion Models with Transformers (DiT)结构解析

AIGC专栏9——Scalable Diffusion Models with Transformers &#xff08;DiT&#xff09;结构解析 学习前言源码下载地址网络构建一、什么是Diffusion Transformer (DiT)二、DiT的组成三、生成流程1、采样流程a、生成初始噪声b、对噪声进行N次采样c、单次采样解析I、预测噪声I…

kitti数据显示

画出track_id publish_utils.py中 def publish_3dbox(box3d_pub, corners_3d_velos, types, track_ids):marker_array MarkerArray()for i, corners_3d_velo in enumerate(corners_3d_velos):marker Marker()marker.header.frame_id FRAME_IDmarker.header.stamp rospy.T…

Pytorch训练RCAN QAT超分模型

Pytorch训练RCAN QAT超分模型 版本信息测试步骤准备数据集创建容器生成文件列表创建文件列表的代码执行脚本,生成文件列表训练RCAN模型准备工作修改开源代码编写训练代码执行训练脚本可视化本文以RCAN超分模型为例,演示了QAT的训练过程,步骤如下: 先训练FP32模型再加载FP32训练…

【随笔】固态硬盘数据删除无法恢复(开启TRIM),注意数据备份

文章目录 一、序二、机械硬盘和固态硬盘的物理结构与工作原理2.1 机械硬盘2.11 基本结构2.12 工作原理 2.2 固态硬盘2.21 基本结构2.22 工作原理 三、机械硬盘和固态硬盘的垃圾回收机制3.1 机械硬盘GC3.2 固态硬盘GC3.3 TRIM指令开启和关闭 四、做好数据备份 一、序 周末电脑突…

【Qt学习】QLineEdit 控件 属性与实例(登录界面,验证密码,正则表达式)

文章目录 1. 介绍2. 实例使用2.1 登录界面2.2 对比两次密码是否相同2.3 通过按钮显示当前输入的密码&#xff08;并对2.2进行优化&#xff09;2.4 结语 3. 正则表达式3.1 QRegExp3.2 验证输入内容 4. 资源代码 1. 介绍 关于 QLineEdit 的详细介绍&#xff0c;可以去查阅官方文…

[计算机网络]--IP协议

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、IP协议…

202432读书笔记|《泰戈尔的诗》——什么事让你大笑,我生命的小蓓蕾

202432读书笔记|《泰戈尔的诗》——什么事让你大笑&#xff0c;我生命的小蓓蕾 《泰戈尔写给孩子的诗&#xff08;中英双语版&#xff09;》作者拉宾德拉纳特泰戈尔文 张王哲图&#xff0c;图文并茂的一本书&#xff0c;文字与图画都很美&#xff0c;相得益彰&#xff01;很值得…

【Memory协议栈】EEPROM Abstraction模块详细介绍

目录 前言 正文 1.功能简介 2.关键概念 3.功能详解 3.1 Addressing scheme and segmentation 3.2 Address calculation 3.3 Limitation of erase / write cycles 3.4 Handling of “immediate” data 3.5 Managing block consistency information 4.关键API定义 4.…

学习磁盘管理

文章目录 一、磁盘接口类型二、磁盘设备的命名三、fdisk分区四、自动挂载五、扩容swap六、GPT分区七、逻辑卷管理八、磁盘配额九、RAID十、软硬链接 一、磁盘接口类型 IDE、SATA、SCSI、SAS、FC&#xff08;光纤通道&#xff09; IDE, 该接口是并口。SATA, 该接口是串口。SCS…

golang学习2,golang开发配置国内镜像

go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct

K8S部署Java项目(Gitlab CI/CD自动化部署终极版)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…