Leetcode 220 Contains Duplicate III

Problem:

Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.

Analyse:

In this problem, we can come up with three methods.

brute force
Obviously, scanning the array with two “for loops” is the most direct method. However, the time complexity will be O(kn) and.the space complexity is O(1), which seems not much efficient.

treeset --> balance tree
In this method, we still need to scan the array one time and store the number into the treeset with the size of k. Luckily, we can get the ceiling and floor of the num by using the property of tree set.
time complexity is O(n)
space complexity is O(nlogk)

bucket --> hashmap
Assuming the length of one bucket is t, any two numbers’ difference in one bucket will smaller than t. So, we would like to build k buckets and put the numbers into the bucket. Then we only need to check each left and right neighbour buckets and itself’s value.
time comlexity is O(n)
space complexity is O(k)



public class Solution1 {
	
//	brute force
	public boolean containsNearbyAlmostDuplicate1(int[] nums, int k, int t) {
		
        // corner case 一般要对input都进行讨论 
	    // k is absolute difference between i and j (不会有任何pair的index的差值等于0)				
		if (nums.length == 0 || nums == null || k <= 0 || t < 0) {
			 return false;
		 }
		
		for (int i=0; i<nums.length; i++) {
			for (int j=i+1; j-i<=k && j<nums.length; j++) {
				if (Math.abs(Long.valueOf(nums[j]) - Long.valueOf(nums[i])) <= t) return true;
			}		
		}
		return false;
	}
	
	
	
	
//	treeset --> balance tree
	 public boolean containsNearbyAlmostDuplicate2(int[] nums, int k, int t) {
         
		 
		 if (nums.length == 0 || nums == null || k <= 0 || t < 0) {
			 return false;
		 }
		 
		 TreeSet<Integer> treeSet = new TreeSet<>();
		 
		 for (int i=0; i<nums.length; i++) {
			 
			 Integer higherNum = treeSet.ceiling(nums[i]);
			 if (higherNum != null && Long.valueOf(higherNum) - Long.valueOf(nums[i]) <= t) {
				 return true;
			 }
			 
			 Integer lowerNum = treeSet.floor(nums[i]);
			 if (lowerNum != null && Long.valueOf(nums[i]) - Long.valueOf(lowerNum) <= t) {
				 return true;
			 }
			 
			 treeSet.add(nums[i]);
			 if (i >= k) {
				 treeSet.remove(nums[i-k]);
			 }		 
		 }	 
		 return false;		 
	 }

	 
//	bucket --> hashmap
	 public boolean containsNearbyAlmostDuplicate3(int[] nums, int k, int t) {
		 
		 if (nums.length == 0 || nums == null || k <= 0 || t < 0 ) return false;
		 
		 int min = Integer.MAX_VALUE;
		 for (int num:nums) {
			 min = Math.min(min, num);
		 }
		 long  diff = Long.valueOf(t) + 1;
		 HashMap<Long, Integer> bucket = new HashMap<>();
		 
		 for (int i=0; i<nums.length; i++) {
			 Long index = ( Long.valueOf(nums[i]) - Long.valueOf(min) ) / diff;
			 
			 // check the left bucket
			 Integer bucket_left = bucket.get(index - 1);
			 if (bucket_left != null && Long.valueOf(nums[i]) - Long.valueOf(bucket_left) <= t) {
				 return true;
			 }
			 
			 // check the right bucket
			 Integer bucket_right = bucket.get(index + 1);
			 if (bucket_right != null && Long.valueOf(bucket_right) - Long.valueOf(nums[i]) <= t) {
				 return true;
			 }
			 
			 // check itself
			 Integer bucket_value = bucket.get(index);
			 if (bucket_value != null) {
				 return true;
			 }
			 
			bucket.put(index, nums[i]);
			
			// we do this step is because we want to reduce the space complexity form O(#buckets) to O(k)
			if (i >= k) {
				bucket.remove(( Long.valueOf(nums[i - k]) - Long.valueOf(min) ) / diff);
			}
			 
		 }

		 return false;
	 }
	 	 
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值