Interval Problems
Level 2.5: Interview Patterns - Master interval manipulation, merging, and scheduling algorithms
Interval Problems Pattern Recognition
🧭 When to Use This Pattern - Checklist
Pattern Recognition Checklist
✅ Use Interval Patterns When:
- 🎯 Time/Range Overlaps: Problems involving overlapping time periods, ranges, or segments
- 📊 Scheduling Conflicts: Managing meetings, events, or resource allocation in time
- 🔍 Merging Operations: Combining overlapping or adjacent intervals
- ⚡ Interval Queries: Finding intersections, gaps, or coverage between intervals
- 🎨 Optimization with Time: Maximizing/minimizing events within time constraints
❌ Don't Use Interval Patterns When:
- 🚫 Point-Based Problems: Dealing with individual points rather than ranges
- 🚫 Non-Temporal Data: Problems not involving time, ranges, or continuity
- 🚫 Complex Dependencies: Intervals with complex dependency relationships
- 🚫 Discrete Optimization: Problems better suited for DP or graph algorithms
🔍 Decision Flowchart:
┌─────────────────────────────────┐ │ Problem Analysis Start │ └─────────────┬───────────────────┘ │ ┌─────────────▼───────────────────┐ │ Does problem involve ranges, │ │ time periods, or intervals? │ └─────────────┬───────────────────┘ │ YES ┌─────────────▼───────────────────┐ │ What operation is needed? │ └─────────────┬───────────────────┘ │ ┌─────────────▼───────────────────┐ │ Choose Pattern Type: │ │ │ │ 🔗 MERGE INTERVALS: │ │ ✓ Combine overlapping │ │ ✓ Sort by start time │ │ ✓ Linear scan and merge │ │ │ │ 🏢 MEETING ROOMS: │ │ ✓ Count simultaneous events│ │ ✓ Event start/end tracking │ │ ✓ Min heap for scheduling │ │ │ │ 📅 INTERVAL SCHEDULING: │ │ ✓ Maximize non-overlapping │ │ ✓ Greedy by end time │ │ ✓ Activity selection │ │ │ │ 🎯 POINT COVERAGE: │ │ ✓ Minimum points to cover │ │ ✓ Sweep line algorithms │ └─────────────────────────────────┘
Merge Intervals
Core Pattern: Sort and Merge
The fundamental approach for merging intervals is to first sort them by start time, then iterate through and merge overlapping intervals. This ensures we process intervals in the correct order.
🌍 Real-World Applications:
📅 Calendar Systems: Merging overlapping appointments and events
🌐 Network Traffic: Combining time windows of high network usage
🏭 Production Planning: Merging overlapping production schedules
📊 Data Analysis: Combining time series data with overlapping periods
TypeScript
// 1. Basic Merge Intervals function merge(intervals: number[][]): number[][] { if (intervals.length <= 1) return intervals; // Sort by start time intervals.sort((a, b) => a[0] - b[0]); const merged: number[][] = [intervals[0]]; for (let i = 1; i < intervals.length; i++) { const current = intervals[i]; const lastMerged = merged[merged.length - 1]; // Check for overlap if (current[0] <= lastMerged[1]) { // Merge intervals lastMerged[1] = Math.max(lastMerged[1], current[1]); } else { // No overlap, add new interval merged.push(current); } } return merged; } // 2. Insert Interval function insert(intervals: number[][], newInterval: number[]): number[][] { const result: number[][] = []; let i = 0; // Add all intervals that end before newInterval starts while (i < intervals.length && intervals[i][1] < newInterval[0]) { result.push(intervals[i]); i++; } // Merge overlapping intervals with newInterval while (i < intervals.length && intervals[i][0] <= newInterval[1]) { newInterval[0] = Math.min(newInterval[0], intervals[i][0]); newInterval[1] = Math.max(newInterval[1], intervals[i][1]); i++; } result.push(newInterval); // Add remaining intervals while (i < intervals.length) { result.push(intervals[i]); i++; } return result; } // 3. Meeting Rooms II - Minimum Rooms Needed function minMeetingRooms(intervals: number[][]): number { if (intervals.length === 0) return 0; // Event point method const events: [number, number][] = []; for (const [start, end] of intervals) { events.push([start, 1]); // Meeting starts events.push([end, -1]); // Meeting ends } // Sort by time, with end events before start events at same time events.sort((a, b) => { if (a[0] !== b[0]) return a[0] - b[0]; return a[1] - b[1]; // End (-1) comes before start (1) }); let currentRooms = 0; let maxRooms = 0; for (const [time, type] of events) { currentRooms += type; maxRooms = Math.max(maxRooms, currentRooms); } return maxRooms; } // Example usage function demonstrateIntervals(): void { console.log("Basic Merge:"); console.log(merge([[1,3],[2,6],[8,10],[15,18]])); // [[1,6],[8,10],[15,18]] console.log("\nMinimum Meeting Rooms:"); console.log(minMeetingRooms([[0,30],[5,10],[15,20]])); // 2 }
Python
# Interval Problems # 1. Basic Merge Intervals def merge(intervals): """Merge overlapping intervals""" if len(intervals) <= 1: return intervals # Sort by start time intervals.sort(key=lambda x: x[0]) merged = [intervals[0]] for current in intervals[1:]: last_merged = merged[-1] # Check for overlap if current[0] <= last_merged[1]: # Merge intervals last_merged[1] = max(last_merged[1], current[1]) else: # No overlap, add new interval merged.append(current) return merged # 2. Insert Interval def insert(intervals, new_interval): """Insert interval and merge if necessary""" result = [] i = 0 # Add all intervals that end before new_interval starts while i < len(intervals) and intervals[i][1] < new_interval[0]: result.append(intervals[i]) i += 1 # Merge overlapping intervals with new_interval while i < len(intervals) and intervals[i][0] <= new_interval[1]: new_interval[0] = min(new_interval[0], intervals[i][0]) new_interval[1] = max(new_interval[1], intervals[i][1]) i += 1 result.append(new_interval) # Add remaining intervals while i < len(intervals): result.append(intervals[i]) i += 1 return result # 3. Meeting Rooms II - Minimum Rooms Needed def min_meeting_rooms(intervals): """Find minimum number of meeting rooms needed""" if not intervals: return 0 import heapq # Sort by start time intervals.sort(key=lambda x: x[0]) # Min heap to track end times of ongoing meetings heap = [] for start, end in intervals: # If earliest ending meeting has ended, remove it if heap and heap[0] <= start: heapq.heappop(heap) # Add current meeting's end time heapq.heappush(heap, end) return len(heap) # Example usage def demonstrate_intervals(): print("Basic Merge:") print(merge([[1,3],[2,6],[8,10],[15,18]])) # [[1,6],[8,10],[15,18]] print("\nMinimum Meeting Rooms:") print(min_meeting_rooms([[0,30],[5,10],[15,20]])) # 2
OCaml
open Printf (* Interval type definition *) type interval = { start: int; finish: int } (* 1. Basic Merge Intervals *) let merge intervals = if Array.length intervals <= 1 then intervals else begin (* Sort by start time *) Array.sort (fun a b -> compare a.start b.start) intervals; let merged = ref [intervals.(0)] in for i = 1 to Array.length intervals - 1 do let current = intervals.(i) in let last_merged = List.hd !merged in if current.start <= last_merged.finish then (* Merge intervals *) let updated = { start = last_merged.start; finish = max last_merged.finish current.finish } in merged := updated :: (List.tl !merged) else (* No overlap, add new interval *) merged := current :: !merged done; Array.of_list (List.rev !merged) end (* Example usage *) let demonstrate_intervals () = let intervals = [| {start=1; finish=3}; {start=2; finish=6}; {start=8; finish=10}; {start=15; finish=18} |] in let merged = merge intervals in printf "Merged intervals: "; Array.iter (fun {start; finish} -> printf "[%d,%d] " start finish) merged; print_newline ()
Problem Type | Time Complexity | Space Complexity | Key Insight |
---|---|---|---|
Basic Merge | O(n log n) | O(1) | Sort by start time, then linear merge |
Insert Interval | O(n) | O(n) | Three phases: before, merge, after |
Meeting Rooms | O(n log n) | O(n) | Min heap or event point method |
🎯 Interview Tips & Pattern Recognition
Interview Strategy Guide
🔍 Recognizing Interval Problems:
- Keywords to Watch: "intervals", "ranges", "overlapping", "merging", "scheduling", "meetings", "time periods"
- Problem Structure: Input contains pairs representing start/end times or ranges
- Common Operations: Merge, intersect, count overlaps, find gaps, optimize scheduling
- Sorting Strategy: Usually sort by start time, sometimes by end time for greedy approaches
💡 Solution Patterns by Problem Type:
- Merge Overlapping: Sort by start → Linear scan → Merge when overlap detected
- Count Simultaneous: Event points method or min heap for active intervals
- Find Non-overlapping: Greedy approach, sort by end time
- Intersection/Union: Two pointers technique or sweep line algorithm
⚠️ Common Pitfalls:
- Boundary Conditions: Clarify if [1,2] and [2,3] overlap (usually they don't)
- Sorting Choice: Start time vs end time - choose based on problem requirements
- Edge Cases: Empty input, single interval, identical intervals
- Data Structure Choice: Array vs heap vs balanced tree - consider time complexity
🌟 Interview Success Framework:
📋 Step 1 - Clarify: "Are touching intervals [1,2] and [2,3] considered overlapping?"
🎯 Step 2 - Identify Pattern: "This looks like a merge/scheduling/counting problem"
📊 Step 3 - Choose Approach: "Sort by start time, then scan/merge/count"
💻 Step 4 - Implement: "Handle sorting, then apply the core algorithm"
🧪 Step 5 - Test Edge Cases: "Empty input, single interval, all overlapping"