Count Integers in Intervals - Complete Solution Guide
Count Integers in Intervals is LeetCode problem 2276, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Given an empty set of intervals, implement a data structure that can: Add an interval to the set of intervals. Count the number of integers that are present in at least one interval. Implement the CountIntervals class: CountIntervals() Initializes the object with an empty set of intervals. void add(int left, int right) Adds the interval [left, right] to the set of intervals. int count() Returns the number of integers that are present in at least one interval. Note that an interval [left, right]
Detailed Explanation
The problem requires designing a data structure, `CountIntervals`, that efficiently manages a set of intervals and can count the total number of integers covered by these intervals. The data structure needs to support two main operations: 1. `add(left, right)`: Adds a new interval `[left, right]` to the existing set of intervals. If the new interval overlaps or is adjacent to existing intervals, they should be merged into a larger interval. 2. `count()`: Returns the total number of integers covered by all the intervals in the set, accounting for overlaps (i.e., each integer should be counted only once).
Solution Approach
The solution uses a sorted list (or vector) of disjoint intervals. When a new interval is added, the following steps are performed: 1. Find the correct position to insert the new interval using binary search (or linear search). 2. Check for overlapping/adjacent intervals to the left and right of the insertion point. 3. Merge overlapping/adjacent intervals into a single, larger interval. 4. Update the total count of covered integers by subtracting the lengths of the original intervals and adding the length of the merged interval. The `count()` operation simply returns the precomputed total count.
Step-by-Step Algorithm
- Step 1: **Initialization**: Create an empty list/vector `intervals` to store disjoint intervals and an integer `total_count` to store the total number of integers covered (initialized to 0).
- Step 2: **`add(left, right)`**: Find the correct insertion point `i` for the new interval `[left, right]` in the sorted `intervals` list.
- Step 3: Check if the interval at `i-1` overlaps or is adjacent to `[left, right]`. If so, update `merged_left` and `merged_right` to encompass the overlapping intervals.
- Step 4: Check if the intervals starting from index `i` overlap or are adjacent to the merged interval. If so, extend the `merged_right` and increment index `i`.
- Step 5: Update the `total_count` by subtracting the length of the intervals that are going to be merged and adding the length of the new merged interval.
- Step 6: Remove the merged intervals from the `intervals` list and insert the new merged interval at the correct position.
- Step 7: **`count()`**: Return the `total_count`.
Key Insights
- Insight 1: The core challenge lies in efficiently merging overlapping intervals. A naive approach of iterating through all intervals for each `add` operation would be too slow.
- Insight 2: Maintaining a sorted list of disjoint intervals allows for binary search (or linear search if list is short) to quickly locate the insertion point and identify intervals that need merging.
- Insight 3: Keeping track of the total count as intervals are added and merged avoids the need to recompute the count from scratch each time `count()` is called, improving performance.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(n)
Topics
This problem involves: Design, Segment Tree, Ordered Set.
Companies
Asked at: Databricks, LinkedIn.