LeetCode 220. Contains Duplicate III

思路分析:
首先,我选择HashSet这种数据结构。对数组nums遍历时,判断是否存在2个元素的差的绝对值小于等于t,若是,则返回true,否则,将元素加入set中,并维持更新set集的大小最大为k。set集中的元素一定是连续不相同的,若存在相同元素,进入循环体进行判断时,相同元素值差绝对值为0,一定小于t(t>=0),则满足所有条件返回true。

设x为set中的元素,-t <= nums[i] - x <= t 推出:
num[i] - t =< x <= nums[i] + t
查找set中是否存在这个值,对set遍历一次即可。所以时间复杂度为:O(n2),空间复杂度为O(n)。

因为nums[i] + t 可能会超过int范围。注意将其转化为long类型。

参考代码:

//220. Contains Duplicate III
	public static boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
		HashSet<Integer> set = new HashSet<Integer>();	
		for(int i=0;i<nums.length;i++){
			long l = (long)nums[i]-(long)t,r = (long)nums[i]+(long)t;
			for(Integer key:set){
				if((long)key>=l&&(long)key<=r)
					return true;
			}			
			set.add(nums[i]);
			//保持set中最多有k个元素
			if(set.size()==k+1){
				set.remove(nums[i-k]);
			}						
		}
	    return false;
	}

算法优化:前面提到,该算法的复杂度为O(n2),通过是没问题,但不是高效率的算法。如果将HashSet改为TreeSet,可以优化到O(nlogn)级别,应该很不错了。因为TreeSet中的元素的有序的,java并且提供了相应的方法,其时间复杂度为O(logn),前面推算得到:
num[i] - t =< x <= nums[i] + t 。

java提供的方法如下:

floor(E e) 方法返回在这个集合中小于或者等于给定元素的最大元素,如果不存在这样的元素,返回null.
ceiling(E e) 方法返回在这个集合中大于或者等于给定元素的最小元素,如果不存在这样的元素,返回null

参考代码:`

public static boolean containsNearbyAlmostDuplicate2(int[] nums, int k, int t) {
		TreeSet<Long> set = new TreeSet<Long>();	
		for(int i=0;i<nums.length;i++){
		
			long l = (long)nums[i]-(long)t,r = (long)nums[i]+(long)t;
			if(set.ceiling((long) l)!=null&&set.ceiling((long) l)<=r){
				return true;
			}
			set.add((long)nums[i]);
			//保持set中最多有k个元素
			if(set.size()==k+1){
				set.remove((long)nums[i-k]);
			}						
		}
	    return false;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值