220. Contains Duplicate III

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

Solution 1

// O(tn)
	public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
		if (nums.length < 2 || k < 1 || t < 0)
			return false;
		ValuePosPair[] valPosArr = new ValuePosPair[nums.length];
		for (int i = 0; i < nums.length; i++)
			valPosArr[i] = new ValuePosPair(nums[i], i);
		Arrays.sort(valPosArr);
		for (int i = 0; i < valPosArr.length; i++) {
			for (int j = i + 1; j < valPosArr.length
					&& ((long) valPosArr[j].val - (long) valPosArr[i].val <= (long) t); j++) {
				if (Math.abs(valPosArr[j].pos - valPosArr[i].pos) <= k)
					return true;
			}
		}
		return false;
	}

	class ValuePosPair implements Comparable<ValuePosPair> {

		int val;
		int pos;

		ValuePosPair(int v, int p) {
			val = v;
			pos = p;
		}

		public int compareTo(ValuePosPair x) {
			return this.val - x.val;
		}
	}

Solution 2

//O(N log K)
	public static boolean containsNearbyAlmostDuplicate2(int[] nums, int k, int t) {
		 if (nums.length < 2 || k == 0) {
		        return false;
		    }
		    TreeSet<Long> set = new TreeSet<>();
		    int i = 0;
		    while(i < nums.length){
		        Long floor = set.floor((long) nums[i]);
		        Long ceiling = set.ceiling((long) nums[i]);
		        if ((floor != null && nums[i] - floor <= t ) ||
		                (ceiling != null && ceiling - nums[i] <= t)) {
		            return true;
		        }
		        set.add((long) nums[i++]);
		        if (i > k) {
		            set.remove((long) nums[i - k - 1]);
		        }
		    }
		    return false;
	}

Solution 3

public static boolean containsNearbyAlmostDuplicate3(int[] nums, int k, int t) {

		if (k < 1 || t < 0 || nums == null || nums.length < 2) {
			return false;
		}
		SortedSet<Long> set = new TreeSet<Long>();
		for (int j = 0; j < nums.length; j++) {
			SortedSet<Long> subSet = set.subSet((long) nums[j] - t, (long) nums[j] + t + 1);
			// 集合不为空,则表示找到解
			if (!subSet.isEmpty()) {
				return true;
			}
			if (j >= k) {
				set.remove((long) nums[j - k]);
			}
			set.add((long) nums[j]);
		}
		return false;
	}

Solution 4

//O(N) bucket
	public boolean containsNearbyAlmostDuplicate4(int[] nums, int k, int t) {
        if (k < 1 || t < 0) return false;
        Map<Long, Long> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            long remappedNum = (long) nums[i] - Integer.MIN_VALUE;
            long bucket = remappedNum / ((long) t + 1);
            if (map.containsKey(bucket)
                    || (map.containsKey(bucket - 1) && remappedNum - map.get(bucket - 1) <= t)
                        || (map.containsKey(bucket + 1) && map.get(bucket + 1) - remappedNum <= t))
                            return true;
            if (map.entrySet().size() >= k) {
                long lastBucket = ((long) nums[i - k] - Integer.MIN_VALUE) / ((long) t + 1);
                map.remove(lastBucket);
            }
            map.put(bucket, remappedNum);
        }
        return false;
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值