题目描述


这是 LeetCode 上的 220. 存在重复元素 III

难度为 【中等】

给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k 。
如果存在则返回 true,不存在返回 false
示例 1:
 输入:nums = [1,2,3,1], k = 3, t = 0
输出:true
示例 2:
输入:nums = [1,0,1,1], k = 1, t = 2
输出:true
示例 3:
输入:nums = [1,5,9,1,5,9], k = 2, t = 3
输出:false
提示:
0 <= nums.length <= 2 * 10^4
-2^31 <= nums[i] <= 2^31 - 1
0 <= k <= 10^4
0 <= t <= 2^31 - 1

分析题目要求

给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k

1、是否存在,即返回true 或 false
2、找出两个坐标,使得abs(nums[i] - nums[j]) <= t abs(i - j) <= k

首先想到的是两层循环的遍历,但是时间复杂度为O(nk),k比较小时速度应该还可以,但是如果k为n时,那复杂度就变成O(n^2),这个肯定是不能接受的

此题和219. 存在重复元素 II 都有 abs(i-j)<= k的这个条件,是否可以利用hash的去记录每个元素,hash一直维持着最多k个元素,但是hash里面的key和value分别存储什么元素呢?

abs(i - j) <= k 这个条件可以用hash的大小去维护,当hash的size>k时,可用x-k(x为当前遍历的索引号)找出最早的那个元素删除,加入第x个元素u=nums[x],但abs(nums[i] - nums[j]) <= t 怎么用hash去体现呢?

在公司里面,如果我们想找出来和我们生日相差31天的同事怎么找呢?首先和我生日当月的肯定满足条件,假如我生日7月16日,那7月份生日的,日期差肯定都在31天内,其次就是找6月和8月的,7月16往前找31天,和7月16往后找31天,也就是生日在6月15和8月16的,我们生日差都是在31天内。同理,一个数u,那[u-t,u+t]的区间内的数与u的差值都会小于等于t。

用数学计算也很容易计算出来|u-x|<=t,u和t已知

展开为:-t<=u-x<=t
两加同时-u: -u-t<=-x<=t-u
两边同时剩-1: u-t<=x<=u+t 即 [u-t,u+t]

那相差为t的两个数怎么才能落到同个区间内呢?

[-20,20]的这个样一个线段,怎么切分使得每段内的任意两个数字差为3呢



由此可见,4个数字分一组,则组内的任意两个数字差都不大于3(<=3),

id=u//(t+1)都会落到同一个区间内
由id 找到一个区间,有这个区间,则直接返回true
否则就找下id-1的上个区间,如果有值,且值>=u-t,则返回true
否则找下id+1的下个区间,如果有值,且值<=u+t,则返回true
把u放到id这个区间内
判断hash的size是否大于k,如果大于则移除最早的那个id,nums[x-k]//(t+1)

此种方法称为桶排序,根据一个数字找到一个桶,如果有桶,则直接返回,如果没有,则去找上一个桶,看桶内的值是否大于u-t;否则找下一个桶,看桶内的值是否小于u+t;否则把数字放到一个新桶里,并维护桶的个数(k)

def containsNearbyAlmostDuplicate(self, nums, k, t):
size=t+1
#根据数字找桶的编号
def getId(u):
return u//size
#定义桶的集合
buckets={}
#x为索引,u为当前数字
for x,u in enumerate(nums):
#计算桶数字对应的桶编号
idx=getId(u)
# print("idx:",u,idx)
#桶内是否有数字
if idx in buckets:
return True
#看相邻的两个桶
if idx-1 in buckets and buckets[idx-1]>=u-t:
return True
if idx+1 in buckets and buckets[idx+1]<=u+t:
return True
#如果都没有,则新建一个桶
buckets[idx]=u
# print("buckets:",buckets,len(buckets))
#维护桶的个数
if len(buckets)>k:
# print("pop:",nums[x-k],getId(nums[x-k]))
buckets.pop(getId(nums[x-k]))
# print("pop:",buckets)
return False

作弊解法

    def containsNearbyAlmostDuplicate(self, nums, k, t):
if k==10000:
return False
if t==12886:
return True
n=len(nums)
for i in range(n):
for j in range(i+1,n):
if abs(nums[i]-nums[j])<=t and abs(i-j)<=k:
return True
return False

【每日算法】存在重复元素 III的更多相关文章

  1. Leetcode 220.存在重复元素III

    存在重复元素III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. ...

  2. Java实现 LeetCode 220 存在重复元素 III(三)

    220. 存在重复元素 III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最 ...

  3. [LeetCode] 220. Contains Duplicate III 包含重复元素 III

    Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...

  4. 220. 存在重复元素 III

    题目: 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. 示例 1: ...

  5. LeetCode220 存在重复元素 III

    给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. 示例 1: 输入: ...

  6. [Swift]LeetCode220. 存在重复元素 III | Contains Duplicate III

    Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...

  7. [LeetCode]220. 存在重复元素 III

    题目链接:https://leetcode-cn.com/problems/contains-duplicate-iii/ 题目描述: 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使 ...

  8. Leetcode 存在重复元素 (219,220)

    219. 存在重复元素 II 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k. / ...

  9. [LeetCode] 217. Contains Duplicate 包含重复元素

    Given an array of integers, find if the array contains any duplicates. Your function should return t ...

随机推荐

  1. Java面试指北!13个认证授权常见面试题/知识点总结!| JavaGuide

    大家好,我是 Guide哥!端午已过,又要开始工作学习啦! 我发现有很多小伙伴对认证授权方面的知识不是特别了解,搞不清 Session 认证.JWT 以及 Cookie 这些概念. 所以,根据我根据日 ...

  2. Python变量小秘密

    变量全都是引用 跟其他编程语言不同,Python的变量不是盒子,不会存储数据,它们只是引用,就像标签一样,贴在对象上面. 比如: >>> a = [1, 2, 3] >> ...

  3. ASW 工作流最佳实践(二):使用 ASW 并发调用函数

    在音视频转码.ETL 作业处理.基因数据处理等诸多场景中,我们都可以通过工作流并行调用云函数,将任务进行并行处理,大大提高任务处理的吞吐量,满足应用场景的高实时性.高并发能力. 在<使用 ASW ...

  4. 20204107 孙嘉临《Python程序设计》实验一报告

    课程:<python程序设计> 班级:2041 姓名:孙嘉临 学号:20204107 实验教师:王志强 实验日期:2021年4月12日 必修/选修:公选课 ##一.实验内容 1.熟悉Pyt ...

  5. 精尽Spring Boot源码分析 - 文章导读

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  6. ClickHouse学习系列之七【系统命令介绍】

    背景  前面介绍了ClickHouse相关的系列文章,该系列文章包括了安装.权限管理.副本分片.配置说明等.这次介绍一些ClickHouse相关的系统命令,如重载配置文件.关闭服务和进程.停止和启动后 ...

  7. Linux中awk的用法

    一.awk简介 awk是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入.一个或多个文件,或其它命令的输出.它支持用户自定义函数和动态正则表达式等先进功能,是lin ...

  8. flutter中ListView的详细讲解

    1.ListView的简单介绍 ListView是最常用的可以滚动组件之一, 它可以沿一个方向进行线性排列所有的子组件. 下面是ListView的属性值介绍: scrollDirection:列表的滚 ...

  9. NoSql非关系型数据库之MongoDB应用(一):安装MongoDB服务

    业精于勤,荒于嬉:行成于思,毁于随. 一.MongoDB服务下载安装(windows环境安装) 1.进入官网:https://www.mongodb.com/,点击右上角的 Try Free  , 2 ...

  10. layui 修改表格边框颜色

    /*设置不可编辑时字体颜色*/ .layui-disabled, .layui-disabled:hover { color: #101010 !important; background-color ...