↓Skip to main content
  1. LeetCode/

LeetCode 220: Contains Duplicate III

·3 mins· ·
LeetCode Hard Sliding-Window Bucket-Sort Ordered-Set Sorting Array
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: hard First Attempt: 2026-01-10

  • Submissions: Wrong Answer ×2 → Output Limit Exceeded → Accepted

Approach
#

Two conditions: index difference <= indexDiff and value difference <= valueDiff.

  • The index condition is a sliding window: keep only the latest indexDiff numbers.
  • The value condition uses buckets of size size = valueDiff + 1, with x in bucket x // size.
    • Two numbers in one bucket differ by <= valueDiff, so return True right away. Hence each bucket holds at most one number.
    • A qualifying number may also sit in a neighboring bucket, so check buckets b - 1 and b + 1.
    • Anything farther differs by > valueDiff.

As the window moves, delete the bucket holding nums[i - indexDiff - 1].

Python’s // floors for negatives, -1 // 3 == -1, so negative numbers bucket correctly too.

My Attempts
#

VersionProblem
Attempts 1–2Deleted expired elements by index (del buckets[i - indexDiff - 1]), but bucket keys are value divided by size; neighbor checks used < valueDiff, missing equality. For nums = [2, 5], indexDiff = 2, valueDiff = 3, `
Attempt 3, OLEFixed, but left a print(buckets) in
ACRemoved the print

Solution
#

class Solution:
    def containsNearbyAlmostDuplicate(self, nums: List[int], indexDiff: int, valueDiff: int) -> bool:
        size = valueDiff + 1
        buckets = {}                               # bucket id -> its only number
        for i, x in enumerate(nums):
            if i > indexDiff:
                del buckets[nums[i - indexDiff - 1] // size]   # leaves the window
            b = x // size
            if b in buckets:
                return True                        # same bucket: difference <= valueDiff
            if b - 1 in buckets and x - buckets[b - 1] <= valueDiff:
                return True
            if b + 1 in buckets and buckets[b + 1] - x <= valueDiff:
                return True
            buckets[b] = x
        return False

The expired number was put in a bucket and never overwritten (overwriting means a shared bucket, which would have returned already), so del always finds it.

Complexity
#

Time O(n), space O(min(n, indexDiff)). An ordered set (SortedList) over the window, querying the smallest value >= x - valueDiff, is the O(n log k) alternative.

Mistakes to Avoid
#

  • Deleting by index: bucket keys are value // size.
  • Neighbor checks need <=.
  • The bucket size is valueDiff + 1, not valueDiff (which divides by zero when valueDiff = 0).
  • Submitting with a print left in.

Interview Explanation
#

A sliding window keeps the latest indexDiff numbers for the index condition, and buckets of size valueDiff + 1 handle the value condition. Two numbers in one bucket always qualify, so each bucket holds at most one; I also check the two neighboring buckets, since farther buckets cannot qualify. As the window moves I delete the expired number’s bucket. Time O(n).

Related

LeetCode 164: Maximum Gap
·3 mins
LeetCode Medium Bucket-Sort Radix-Sort Sorting Array
LeetCode 164 note: the maximum gap is at least the average gap, so with buckets no wider than that it lies between consecutive non-empty buckets; keep each bucket’s min and max for O(n)
LeetCode 3634: Minimum Removals to Balance Array
·2 mins
LeetCode Medium Sliding-Window Sorting Binary-Search Array
LeetCode 3634 note: after sorting, what remains is always a contiguous block; for each minimum nums[left], a right-only pointer finds how far it can extend, and everything outside is removed
LeetCode 594: Longest Harmonious Subsequence
·1 min
LeetCode Easy Array Hash-Table Sliding-Window Sorting
LeetCode 594 note: subsequences need not be contiguous, so just count; for each x add the counts of x and x + 1
LeetCode 2156: Find Substring With Given Hash Value
·3 mins
LeetCode Hard Sliding-Window Rolling-Hash String
LeetCode 2156 note: the first character has weight p^0, so sliding right to left needs only multiply by p, add the new character, and subtract the outgoing one times p^k; the modulus may not be prime, so no modular inverse
LeetCode 2953: Count Complete Substrings
·3 mins
LeetCode Hard Sliding-Window Hash-Table String
LeetCode 2953 note: split where neighboring letters differ by more than 2; in each segment enumerate the number of distinct letters d, slide a fixed window of d × k, and track how many letters appear exactly k times
LeetCode 3795: Minimum Subarray Length With Distinct Sum At Least K
·2 mins
LeetCode Medium Sliding-Window Hash-Table Array
LeetCode 3795 note: a shortest-window slide where each value counts once; track each value’s last position, and subtract the left value only if it was the last occurrence