面试经典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://xiahunao.cn/news/2809756.html

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

相关文章

BUU [CISCN2019 华东南赛区]Web4

BUU [CISCN2019 华东南赛区]Web4 题目描述&#xff1a;Click to launch instance. 开题&#xff1a; 点击链接&#xff0c;有点像SSRF 使用local_file://协议读到本地文件&#xff0c;无法使用file://协议读取&#xff0c;有过滤。 local_file://协议&#xff1a; local_file…

算能RISC-V通用云开发空间编译pytorch @openKylin留档

终于可以体验下risc-v了&#xff01; 操作系统是openKylin&#xff0c;算能的云空间 尝试编译安装pytorch 首先安装git apt install git 然后下载pytorch和算能cpu的库&#xff1a; git clone https://github.com/sophgo/cpuinfo.git git clone https://github.com/pytorc…

比创达元启新程 共创新佳绩:2023年度总结暨迎新年晚会圆满收官!

新的一年&#xff0c;万象更新。回顾2023年&#xff0c;我们携手走过的岁月&#xff0c;喜悦伴着汗水&#xff0c;成功伴着艰辛&#xff0c;遗憾激励奋斗。在过去的一年时间里&#xff0c;每个行业都经历着前所未有的变革与困难。我们比创达人也凭借着人心齐泰山移的团结之力&a…

Spring Boot 项目集成camunda流程引擎

使用camunda开源工作流引擎有&#xff1a;通过docker运行、使用springboot集成、部署camunda发行包、基于源代码编译运行等多种方式。 其中&#xff0c;通过源代码编译运行的方式最为复杂&#xff0c;具体参考&#xff1a;https://lowcode.blog.csdn.net/article/details/1362…

图片录入设备、方式与质量对图片转Excel的影响

随着数字化时代的到来&#xff0c;图片已经成为人们日常生活中不可或缺的一部分。在各行各业中&#xff0c;图片的应用越发广泛&#xff0c;从而促使了图片处理技术的快速发展。然而&#xff0c;图片的质量对于后续数据处理和分析的准确性和可靠性有着至关重要的影响。本文将从…

Windows系统搭建Elasticsearch引擎结合内网穿透实现远程连接查询数据

文章目录 系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 Elasticsearch是一个基于Lucene库的分布式搜索和分析引擎&#xff0c;它提供了一个分布式、多…

HTB-Bizness

一、信息收集 访问ip自动跳转域名&#xff0c;host绑定域名后访问 目录爆破 有一个登录目录&#xff0c;访问发现是apahce ofbiz登录页面 发现存在漏洞 二、漏洞利用 在github上找到了图形化利用工具 使用工具反弹shell 得到flag 三、权限提升 从本地利用python开启http服务…

Android RecyclerView 如何展示自定义列表 Kotlin

Android RecyclerView 如何展示自定义列表 Kotlin 一、前提 有这么一个对象 class DeviceDemo (val name: String, val type: String, val address: String)要展示一个包含这个对象的列表 bluetoothDevices.add(DeviceDemo("bb 9800", "LE", "32:…

蛇形矩阵3

题目描述 把数1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;…&#xff0c;N*N按照“蛇形3”放入N*N矩阵的中&#xff0c;输出结果。 下面是N6的蛇形3的图示 输入格式 第一行1个正整数&#xff1a;N&#xff0c;范围在[1,100]。 输出格式 N行&#x…

docker 容器访问 GPU 资源使用指南

概述 nvidia-docker 和 nvidia-container-runtime 是用于在 NVIDIA GPU 上运行 Docker 容器的两个相关工具。它们的作用是提供 Docker 容器与 GPU 加速硬件的集成支持&#xff0c;使容器中的应用程序能够充分利用 GPU 资源。 nvidia-docker 为了提高 Nvidia GPU 在 docker 中的…

Linux系统前后端分离项目

目录 一.jdk安装 二.tomcat安装 三.MySQL安装 四.nginx安装 五.Nginx负载均衡tomcat 六.前端部署 一.jdk安装 1. 上传jdk安装包 jdk-8u151-linux-x64.tar.gz 进入opt目录&#xff0c;将安装包拖进去 2. 解压安装包 这里需要解压到usr/local目录下&#xff0c;在这里新建一个…

力扣思路题:丑数

此题的思路非常奇妙&#xff0c;可以借鉴一下 bool isUgly(int num){if(num0)return false;while(num%20)num/2;while(num%30)num/3;while(num%50)num/5;return num1; }

学会玩游戏,智能究竟从何而来?

最近在读梅拉妮米歇尔《AI 3.0》&#xff0c;第九章谈到学会玩游戏&#xff0c;智能究竟从何而来&#xff1f; 作者: [美] 梅拉妮米歇尔 出版社: 四川科学技术出版社湛庐 原作名: Artificial Intelligence: A Guide for Thinking Humans 译者: 王飞跃 / 李玉珂 / 王晓 / 张慧 …

Xcode与Swift开发小记

引子 鉴于React Native目前版本在iOS上开发遇到诸多问题&#xff0c;本以为搞RN只需理会Javascript开发&#xff0c;没想到冒出CocoaPod的一堆编译问题。所以横下一条心&#xff0c;决定直接进攻iOS本身。不管你是用React Native&#xff0c;还是用Flutter&#xff0c;iOS下的…

网站开发--详解Servlet

&#x1f495;"Echo"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;网站开发–详解Servlet 一.基本介绍 tomcat是Java中开发服务器的重要的一个工具,任何开发的服务器都要部署在tomcat之上,可以说tomcat是所有服务器的底座,为了更好的操作http,to…

配置多个后端 API 代理

在开发 React 应用时&#xff0c;通常会涉及到与后端 API 的交互。而在开发过程中&#xff0c;我们经常需要在开发环境中使用代理来解决跨域请求的问题。Create React App 提供了一种简单的方式来配置代理&#xff0c;即通过创建一个名为 setupProxy.js 的文件来配置代理规则。…

Linux之安装jdk,tomcat,mysql,部署项目

目录 一、操作流程 1.1安装jdk 1.2安装tomcat&#xff08;加创建自启动脚本&#xff09; 1.3 安装mysql 1.4部署项目 一、操作流程 首先把需要用的包放进opt文件下 1.1安装jdk 把jdk解压到/usr/local/java里 在刚刚放解压包的文件夹打开vim /etc/profile编辑器&#xff0c…

高防服务器的原理

高防服务器的原理是什么?高防服务器的原理可以从哪些方面解读&#xff0c;小编为您整理发布高防服务器的工作原理主要基于以下几个方面&#xff1a; - **防火墙配置**&#xff1a;在服务器的节点上配置防火墙&#xff0c;能够自动过滤网络恶意攻击&#xff0c;提高网络安全性。…

Linux之部署前后端分离项目

Nginx配置安装 1.安装依赖 我们这里安装的依赖是有4个的 [rootlocalhost opt]# yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 2.上传解压安装包 [rootlocalhost opt]# tar -xvf nginx-1.13.7.tar.gz -C /usr/local/java/3.安装Nginx &#xff0…

聚观早报 | OPPO公布全新AI战略;华为P70 Art影像细节曝光

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 2月22日消息 OPPO公布全新AI战略 华为P70 Art影像细节曝光 苹果正加速开发智能戒指 微软将大规模投资人工智能 …