【每日算法】存在重复元素 III
题目描述
这是 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的更多相关文章
- Leetcode 220.存在重复元素III
存在重复元素III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. ...
- Java实现 LeetCode 220 存在重复元素 III(三)
220. 存在重复元素 III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最 ...
- [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 ...
- 220. 存在重复元素 III
题目: 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. 示例 1: ...
- LeetCode220 存在重复元素 III
给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. 示例 1: 输入: ...
- [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 ...
- [LeetCode]220. 存在重复元素 III
题目链接:https://leetcode-cn.com/problems/contains-duplicate-iii/ 题目描述: 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使 ...
- Leetcode 存在重复元素 (219,220)
219. 存在重复元素 II 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k. / ...
- [LeetCode] 217. Contains Duplicate 包含重复元素
Given an array of integers, find if the array contains any duplicates. Your function should return t ...
随机推荐
- 【题解】poj 3162 Walking Race 树形dp
题目描述 Walking RaceTime Limit: 10000MS Memory Limit: 131072KTotal Submissions: 4941 Accepted: 1252Case ...
- Java的一些细节语法(不定时更新。。。)
可信考试Java相关题目 目录 可信考试Java相关题目 ConcurrentHashMap不允许key为null,但是HashMap是可以的.TreeMap key不支持null. 以下代码里面,请 ...
- centos7安装JDK、CentOS
1.安装JDK 1.1查看系统是否已有自带的JDK rpm -qa |grep java rpm -qa |grep jdk rpm -qa |grep gcj 1.2卸载已有安装 如果没有输出信息, ...
- Python常用数据结构(列表)
Python中常用的数据结构有序列(如列表,元组,字符串),映射(如字典)以及集合(set),是主要的三类容器 内容 序列的基本概念 列表的概念和用法 元组的概念和用法 字典的概念和用法 各类型之间的 ...
- Java-学习日记(Java8异步)
今天用到的中异步操作:异步编程与异步处理数据 //里面返回其他接口服务使用CompletableFuture CompletableFuture.runAsync(()->{ driverNoR ...
- 如何优雅的实现Mysql 增删改查,看完你就会了
接着上期说,上期没写一条sql就把数据查询出来了,那如果要保存或者更新数据怎么办呢?能不能自己写sql呢? 保存数据 @GetMapping("save")//保存数据 publi ...
- 01-Tkinter教程-窗口的管理与设置
Tkinter介绍 官方用的GUI工具包--Tkinter(IDLE就是用这个开发的). Tkinter是Python的标准GUI库,它实际是建立在Tk技术上的.在大多数Unix平台以及Windows ...
- Python如何设计面向对象的类(上)
Python是一门高级语言,支持面向对象设计,如何设计一个符合Python风格的面向对象的类,是一个比较复杂的问题,本文提供一个参考,表达一种思路,探究一层原理. 目标 期望实现的类具有以下基本行为: ...
- 乘风破浪,Windows11设计和开发指导,全新图标字体和云母材质
Windows11全新的布局设计 Windows 11全新的布局设计已设计为支持现代应用体验.渐进的圆角.嵌套元素和一致的排水沟相结合,营造出柔和.平静.平易近人的效果,强调目的的统一和易用性. ht ...
- 从零开始学前端,React框架背后的核心机制和原理JSX
什么是React React是起源于Facebook的一个前端框架,用于构建用户界面的JavaScript库,Facebook用来探索一种更加高效优雅的Javascript MVC框架来架设Insta ...