top of page

Contains Duplicate Within K Distance

  • mosesg1123
  • May 9
  • 4 min read

Checking for nearby repeated events in a log or sensor stream is a common task in monitoring, fraud detection, and real‑time analytics. The “Contains Duplicate Within K Distance” problem forces you to manage temporal windows and fast membership checks efficiently.


Problem Statement

Given an integer array nums and an integer k, determine whether there are two distinct indices i and j in the array such that nums[i] == nums[j] and |i - j| <= k. Return true if such a pair exists, otherwise false.

Index:  0   1   2   3   4
Nums:  [1,  2,  3,  1,  2]
                    ↑
                    1 at index 3 matches 1 at index 0 (distance 3)

1. Clarify Requirements Before Jumping Into Code

  • Can k be zero or negative? Assume k > 0

  • Are array values arbitrary 32‑bit ints? Yes.

  • Array length bounds? Up to, say, 10⁵.

  • Should duplicates farther apart than k be ignored? Yes.


2. Identify the Category of the Question

This is a sliding‑window + hash problem. Common patterns:

  • Fixed‑size window maintenance

  • Hash‑set for fast membership

  • Hash‑map of most‑recent indices

  • Two‑pointer window contraction/expansion


3. Consider a Brute‑Force Approach to Understand the Problem

Brute‑force: for each index i, scan the next k positions j = i+1 … i+k and check if nums[i] == nums[j].

for i from 0 to n-1:
  for j from i+1 to min(n-1, i+k):
    if nums[i] == nums[j]: return true
return false

Time: O(n·k) which in worst case is O(n²).

Space: O(1)

This solution is too slow if both n and k are large.


4. Brainstorm More Solutions

Option 1:

The brute-force solution involves a lot of repeated work: I'm rescanning elements repeatedly to see if they are duplicates.


So to try and optimize, the first question I ask myself is: How can I quickly determine whether or not I've seen a particular element within K steps?

Hash Sets and Maps shine when it comes to constant look up time of elements! So how about I start with a hash set to track the last k elements that I've seen.


That naturally leads to a second question: How do I clean up the hash set to ensure that I am only tracking the last K elements?

This is sounding a lot like a sliding window! Every time I move forward one element in the array, I know exactly which element needs to drop from my hash set: nums[i-k].


Combining these two ideas:

  • Keep a hash‑set of up to k most recent values.

  • At index i:

    1. If nums[i] in set → return true.

    2. Add nums[i] to set.

    3. If set size > k, remove nums[i-k].

  • Time: O(n), Space: O(k).


Option 2

Let's say I know there is at least one duplicate in the array. How would I know if they are within K elements? Easy, by comparing indices: i -j <= k


If I'm at element i, I have two of the three variables that I need. I'm just missing j, the index of the duplicate. How can I quickly identify the index of that element?

With a hash map!


I maintain a hash map where the key is the element from the array, and the value is the index of that element, then I can look up in constant time the index of j to calculate if it's within k distance!


But what if the same element appears 3 or more times in the array? I can just update the map entry for that element to ensure it's up-to-date with the most recent index for that element.


So to summarize this idea:

  • In my map lastIndex, store the pair {element, index}.

  • When I see num again at index i, check if i - lastIndex[element] <= k.

  • If yes, return true; otherwise update lastIndex[num] = i.

  • Time: O(n), Space: O(n).


Both solutions are equally valid and you are unlikely to be penalized for either decision. Option 2 does seem a bit cleaner than Option 1 though: one pass, one lookup, one update per element. It avoids explicitly managing the window size which should lead to slightly simpler code while enforcing the distance constraint. So that's the solution we'll choose for this post!


5. Discuss Trade‑Offs Between Your Solutions

Approach

Time

Space

Pros

Cons

Brute‑force nested scan

O(n·k)

O(1)

Simple

Too slow when k or n is large

Sliding‑window with hash‑set

O(n)

O(k)

Fast, bounded space

Needs explicit eviction logic

Hash‑map of last indices

O(n)

O(n)

Simplest code, direct distance check

Slightly more space if many uniques

6. Optimal Solution Recap

Maintain a hash‑map of { element, mostRecentIndex }. For each i, if element is in the hash-map with most recent index j, and i - j <= k, return true; otherwise update the mostRecentIndex for that element.


7. Write Pseudocode to Structure Your Thoughts

function containsNearbyDuplicate(nums, k):
  map = empty hash‑map (value → last index)
  for i from 0 to nums.length-1:
    if nums[i] in map and i - map[nums[i]] <= k:
      return true
    map[nums[i]] = i
  return false

8. Consider Edge Cases

  • Empty array or single element → return false.

  • k = 0 → never match two distinct indices → return false.

  • All distinct values → return false.

  • Immediate duplicate at distance = k → should return true.

  • Large k greater than array length → equivalent to checking any duplicate.


9. Write Full Code Syntax

import java.util.HashMap;

public class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        if (k <= 0) return false;
        HashMap<Integer, Integer> lastIndex = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            Integer prev = lastIndex.get(nums[i]);
            if (prev != null && i - prev <= k) {
                return true;
            }
            lastIndex.put(nums[i], i);
        }
        return false;
    }
}

10. Test Your Code

public static void main(String[] args) {
    Solution sol = new Solution();

    // no duplicates
    System.out.println(sol.containsNearbyDuplicate(new int[]{1,2,3,4}, 2) == false);

    // duplicate within k
    System.out.println(sol.containsNearbyDuplicate(new int[]{1,2,3,1}, 3) == true);

    // duplicate but too far apart
    System.out.println(sol.containsNearbyDuplicate(new int[]{1,2,3,1}, 2) == false);

    // k = 0
    System.out.println(sol.containsNearbyDuplicate(new int[]{1,1}, 0) == false);

    // multiple duplicates
    System.out.println(sol.containsNearbyDuplicate(new int[]{1,0,1,1}, 1) == true);
}

11. Key Lessons to Remember for Future Questions

  • A hash‑map of value→index lets you enforce distance constraints in one pass.

  • Sliding‑window with a hash‑set is another pattern for “within k” problems, trading off eviction logic for simpler maps.

  • Always ask about edge cases like k=0, arrays of length ≤1, and large k values.

  • Breaking problems into “fast membership” and “distance check” clarifies your approach.

  • Writing clear pseudocode first prevents off‑by‑one errors in index arithmetic.


Good Luck and Happy Coding!

Recent Posts

See All
Non-Overlapping Intervals

Learn how to solve the Non-Overlapping Intervals coding problem to prepare for your next technical interview!

 
 
 
Merge Intervals

"Merge Intervals" is one of those classic algorithm problems that shows up frequently in technical interviews. It's a great test of your...

 
 
 
Jump Game II

Jump Game II is a classic follow-up to the original Jump Game problem. It’s not just about whether you can reach the end... now you have to do it in the fewest jumps possible! That small change turns

 
 
 

Comments

Couldn’t Load Comments
It looks like there was a technical problem. Try reconnecting or refreshing the page.

Drop Me a Line, Let Me Know What You Think

Thanks for submitting!

© 2023 by Train of Thoughts. Proudly created with Wix.com

bottom of page