给你一个整数数组 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 * 104
-231 <= nums[i] <= 231 - 1
0 <= k <= 104
0 <= t <= 231 - 1
注意:本题与主站 220 题相同: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
LCR 057. 存在重复元素 III - 力扣(LeetCode)
思路一:暴力,看x的前k个元素有没有满足条件的,挨个判断。复杂度太高
思路二:题目可以转化为:在当前元素nums[i]下,寻找前k个元素中有没有元素使得其在区间[nums[i]-t,nums[i]+t]之间。这需要一个数据结构:1.支持新增和删除元素,维护滑动窗口。2.内部元素有序,可以判断是否有区间内元素。有序集合TreeSet,内部由红黑树实现。
代码:
class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
TreeSet set=new TreeSet();
for(int i=0;i=k) set.remove((long)nums[i-k]);
}
return false;
}
}
tips:一般写List=new ArrayList,即抽象而不是实现,后续无论是array还是linked,都可以解耦修改。但是当需要用到ArrayList特有的方法时就只能写ArrayList=。例如本题目中的ceiling,floor方法
思路三:桶排序,每t+1个元素放在一个桶中,这样桶中差值最大即为t(例如0,1,2最大差值为2,t=2但总数=3).然后当前元素x,如果k内有同桶元素即true,若没有则查看相邻桶再做判断。因为区间为[x-t,x+t],因此最大最小可能绝对不会出相邻桶。关于分桶,x>0,[0,t]=0(特殊情况,不套n),[t+1,2t+1]=1,[(n)t+1,(n+1)t+1]=n。x<0,[-t,-1]=-1,[-t-1,-2t-1]=-2,[-(n+1)t-1,-(n)t-1]=-n.所以x>0时桶号n=x/t+1=x/w。x<0时,桶号n=x+1/t=x+1/w-1。除法会自动向上取整,正负数的上不一样,即向0靠近。
用map
为什么只留一个值可以确保?比如桶[1][3],[1][4]当桶里只有一个元素时,t=2,[0,1,2][3,4,5].查1时3满足,4不满足.若nums没有3或13距离过远,则不考虑;若有3且满足下标差 下标的话,只保留x之前k个元素的值在桶里,因此只要桶里有,就true 代码:class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
long w = (long) t + 1;
Map