[LintCode/LeetCode] Contains Duplicate III

linspiration發表於2019-01-19

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.

Example

Given nums = [1,3,1], k = 1, t = 1, return false.

Solution

Brute force


public class Solution {
    /**
     * @param nums: the given array
     * @param k: the given k
     * @param t: the given t
     * @return: 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.
     */
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        // Write your code here
        for (int i = 0; i < nums.length; i++) {
            for (int j = i+1; j < nums.length; j++) {
                if (Math.abs(j-i) <= k && Math.abs(nums[i]-nums[j]) <= t) return true;
            }
        }
        return false;
    }
}

Maintain a size k window

public class Solution {
    /**
     * @param nums: the given array
     * @param k: the given k
     * @param t: the given t
     * @return: 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.
     */
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        // Write your code here
        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) && Math.abs(reMappedNum - map.get(bucket-1)) <= t) ||
              (map.containsKey(bucket+1) && Math.abs(reMappedNum - map.get(bucket+1)) <= t)) {
                return true;    
            }
            if (i >= k) {
                long lastBucket = ((long)nums[i-k] - Integer.MIN_VALUE) / ((long)t + 1);
                map.remove(lastBucket);
            }
            map.put(bucket, reMappedNum);
        }
        return false;
    }
}

相關文章