Problem: Contain duplicate III

Posted by Marcy on February 18, 2015

Question

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 1:

Input: nums = [1,2,3,1], k = 3, t = 0
Output: true

Example 2:

Input: nums = [1,0,1,1], k = 1, t = 2
Output: true

Example 3:

Input: nums = [1,5,9,1,5,9], k = 2, t = 3
Output: false

Solution

This problem requires to maintain a window of size k of the previous values that can be queried for value ranges. The best data structure to do that is Binary Search Tree. As a result maintaining the tree of size k will result in time complexity O(N lg K). In order to check if there exists any value of range abs(nums[i] - nums[j]) to simple queries can be executed both of time complexity O(lg K).

Here is the whole solution using TreeSet. TreeSet is implemented using a tree structure (Red-black tree in algorithm book, a red–black tree is a kind of self-balancing binary search tree). The elements in a set are sorted, but the add, remove, and contains methods has time complexity of O(log (n)).

Code

Here is a sample solution.

class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        if(k==0) return false;
        TreeSet<Long> set = new TreeSet();
        for(int i=0; i<nums.length; i++) {
            Long ceiling = set.ceiling((long)nums[i]);
            Long floor = set.floor((long)nums[i]);
            if(floor != null && nums[i] - floor <= t) return true;
            if(ceiling != null && ceiling - nums[i] <= t) return true;
            
            if(set.size()==k) set.remove((long)nums[i-k]);
            
            set.add((long)nums[i]);
        }
        
        return false;
    }
}

Performance

O(N lg K) time complexity as discussed.

Notes

TreeSet: balanced BST O(logn) insert/delete

-

ceiling element floor - - -