220. Contains Duplicate III

来源:互联网 发布:oracle sql执行顺序 编辑:程序博客网 时间:2024/06/05 00:52

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) bucketpublic 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