题目描述


这是 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. JVM集合之开篇点题

    大家在平时的开发过程中是否遇到过StackOverflowError.OutOfMemoryError等类似的内存溢出错误呢?大家又是怎么解决这个问题的?再来,大家在面试过程中有没有被面试官提问过jv ...

  2. halcon——缺陷检测常用方法总结(测量拟合)

    引言 机器视觉中缺陷检测分为一下几种: blob分析+特征 模板匹配(定位)+差分:halcon--缺陷检测常用方法总结(模板匹配(定位)+差分) - 唯有自己强大 - 博客园 (cnblogs.co ...

  3. raft 图解 (秒懂)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  4. 11张流程图帮你搞定 Spring Bean 生命周期

    在网上已经有跟多Bean的生命周期的博客,但是很多都是基于比较老的版本了,最近吧整个流程化成了一个流程图.待会儿使用流程图,说明以及代码的形式来说明整个声明周期的流程.注意因为代码比较多,这里的流程图 ...

  5. Java安全之反序列化回显研究

    Java安全之反序列化回显研究 0x00 前言 续上文反序列化回显与内存马,继续来看看反序列化回显的方式.上篇文中其实是利用中间件中存储的Request 和Response对象来进行回显.但并不止这么 ...

  6. token & refresh token 机制总结

    token & refresh token 机制总结 废话 我在项目上写了个配置页面,之前很简单直接登录,毕竟配置页面自己人用就没有做token机制,后来公司的安全审核不过,现在要加上toke ...

  7. Linux 中的 AutoHotKey 键映射替代方案

    1. Windows 之 AutoHotKey 初次了解AutoHotKey,是在Win 下最爱效率神器:AutoHotKey | 晚晴幽草轩这篇博客中,博主有对AutoHotKey作详细介绍,这里不 ...

  8. 第5章:资源编排(YAML)

    5.1 编写YAML注意事项 YAML 是一种简洁的非标记语言. 语法格式: 缩进表示层级关系 不支持制表符"tab"缩进,使用空格缩进 通常开头缩进 2 个空格 字符后缩进 1 ...

  9. 2018-10-14普及模拟赛」Hash 键值 (hash)

    今天,带大家看一看一道思维题... Hash 键值 (hash) 题目描述 Marser沉迷hash无法自拔,然而他发现自己记不住hash键值了-- Marser使用的hash函数是一个单纯的取模运算 ...

  10. CentOS7 安装搭建docker环境

    一.Docker简介 Docker 版本 :版本分为:社区版CE  企业版EE 社区版分为stable和edge俩种发行方式: stable版本:是季度版发行(三月一更新) edge版本:是月度版发行 ...