Range Module - Problem
Design and implement a Range Module - a data structure that efficiently tracks ranges of numbers and supports dynamic operations on them.
Your Range Module should handle half-open intervals [left, right), which include all real numbers x where left โค x < right.
Key Operations:
addRange(left, right)- Add all numbers in[left, right)to tracking. If some numbers are already tracked, merge the ranges intelligently.queryRange(left, right)- Returntrueif every number in[left, right)is currently tracked.removeRange(left, right)- Stop tracking all numbers in[left, right), potentially splitting existing ranges.
Example: After addRange(10, 20) and addRange(15, 25), the module tracks [10, 25). Then queryRange(12, 18) returns true, but removeRange(14, 16) would split this into [10, 14) and [16, 25).
Input & Output
example_1.py โ Basic Operations
$
Input:
rangeModule = RangeModule()
rangeModule.addRange(10, 20)
rangeModule.removeRange(14, 16)
rangeModule.queryRange(10, 14)
rangeModule.queryRange(13, 16)
rangeModule.queryRange(16, 17)
โบ
Output:
[null, null, null, true, false, true]
๐ก Note:
After addRange(10,20), we track [10,20). removeRange(14,16) splits this into [10,14) and [16,20). queryRange(10,14) returns true (fully covered), queryRange(13,16) returns false (partially covered), queryRange(16,17) returns true (fully covered).
example_2.py โ Merging Ranges
$
Input:
rangeModule = RangeModule()
rangeModule.addRange(1, 5)
rangeModule.addRange(7, 10)
rangeModule.addRange(4, 8)
rangeModule.queryRange(1, 10)
โบ
Output:
[null, null, null, null, true]
๐ก Note:
First we have [1,5) and [7,10). Adding [4,8) merges all three into [1,10) since [4,8) overlaps with both existing ranges. queryRange(1,10) returns true as the entire range is covered.
example_3.py โ Edge Cases
$
Input:
rangeModule = RangeModule()
rangeModule.queryRange(1, 5)
rangeModule.addRange(1, 1)
rangeModule.queryRange(1, 1)
โบ
Output:
[null, false, null, true]
๐ก Note:
Initially no ranges are tracked, so queryRange(1,5) returns false. addRange(1,1) adds an empty range (since [1,1) contains no numbers). queryRange(1,1) for empty range returns true.
Visualization
Tap to expand
Understanding the Visualization
1
Book Rooms 10-20
Guest books rooms 10 through 19 (20 exclusive)
2
Book Rooms 15-25
Another guest books 15-24, merges with existing booking to create 10-25
3
Check Availability 12-18
Query if rooms 12-17 are all booked (yes, covered by 10-25)
4
Cancel Rooms 17-22
Cancel booking for rooms 17-21, splits 10-25 into 10-17 and 22-25
Key Takeaway
๐ฏ Key Insight: By maintaining sorted, non-overlapping intervals and using binary search, we can efficiently handle dynamic range operations in O(log n) to O(n) time while using minimal O(k) space.
Time & Space Complexity
Time Complexity
O(R) per operation where R is range size
Each operation processes every number in the range individually
โ Linear Growth
Space Complexity
O(N) where N is total numbers tracked
Stores each tracked number separately
โก Linearithmic Space
Constraints
- 1 โค left < right โค 109
- At most 104 calls will be made to addRange, queryRange, and removeRange
- Half-open intervals: [left, right) includes left but excludes right
๐ก
Explanation
AI Ready
๐ก Suggestion
Tab
to accept
Esc
to dismiss
// Output will appear here after running code