Date Ranges Analysis
Maximum Occurrence Date
Algorithm Development
Data Processing
Programming Challenge

Given a list of date ranges, find a date which occurs maximum times

Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms

Introduction

Given several inclusive date ranges, the goal is to find the date covered by the largest number of ranges. The naive solution checks every day in every range, which works for tiny inputs but becomes wasteful when ranges span months or years. A better approach is a sweep-line algorithm using boundary events.

The Key Idea: Add at the Start, Subtract After the End

Suppose a range covers every day from 2025-01-03 through 2025-01-07, inclusive. Instead of incrementing five separate dates, record two events:

  • '+1 on 2025-01-03'
  • '-1 on 2025-01-08'

Then sort all events by date and scan from left to right, keeping a running total. Whenever the running total increases past the best value seen so far, the current date is the new answer.

This works because the running total represents how many ranges are active on that date.

A Runnable Python Solution

python
1from collections import defaultdict
2from datetime import date, timedelta
3
4ranges = [
5    (date(2025, 1, 1), date(2025, 1, 5)),
6    (date(2025, 1, 2), date(2025, 1, 4)),
7    (date(2025, 1, 4), date(2025, 1, 7)),
8    (date(2025, 1, 4), date(2025, 1, 6)),
9]
10
11
12def max_covered_date(date_ranges):
13    events = defaultdict(int)
14
15    for start, end in date_ranges:
16        if end < start:
17            raise ValueError("end date must be on or after start date")
18        events[start] += 1
19        events[end + timedelta(days=1)] -= 1
20
21    current = 0
22    best_count = -1
23    best_date = None
24
25    for day in sorted(events):
26        current += events[day]
27        if current > best_count:
28            best_count = current
29            best_date = day
30
31    return best_date, best_count
32
33
34best_day, count = max_covered_date(ranges)
35print(best_day, count)

For the sample input, the answer is 2025-01-04 with coverage count 4.

Why This Is Better Than Expanding Every Day

A day-by-day frequency array is easy to understand, but it becomes expensive when the date span is large. If your earliest date is in January and your latest date is two years later, you would allocate and update many more days than necessary.

The sweep-line version scales with the number of ranges, not with the full size of the calendar interval. For n ranges, you create at most 2n event dates and then sort them.

That makes the time complexity roughly:

  • 'O(n log n) for sorting event dates'
  • 'O(n) additional scanning work'

This is usually much better than touching every day in every range.

Handling Ties

If several dates share the same maximum count, you need a tie rule. The implementation above returns the earliest date where the maximum is reached because it updates the answer only when current > best_count.

If instead you wanted the latest such date, you could change the comparison rule or record all maximal segments during the scan.

Being explicit about ties is important in interview questions and production code alike.

What About DateTimes Instead of Dates

The same event idea works for timestamps too, but you must define the interval semantics carefully.

With plain dates, inclusive ranges are natural, so subtracting on the day after end is easy. With timestamps, you often switch to half-open intervals, meaning start <= t < end, to avoid ambiguity around seconds, milliseconds, and timezone conversions.

If the original problem really is about calendar days, use date instead of datetime. It keeps the logic clean.

Common Pitfalls

The most common mistake is forgetting that the end date is inclusive. If you subtract on end instead of end + 1 day, the result is off by one.

Another mistake is expanding every date when the date span is huge. That can turn an elegant range problem into a memory-heavy brute-force solution.

A third pitfall is ignoring invalid input where end < start. Detect it early and fail clearly.

Summary

  • Use a sweep-line algorithm instead of counting every day in every range.
  • Record +1 at each start date and -1 on the day after each inclusive end date.
  • Sort the event dates and scan with a running total.
  • Decide how ties should be handled, usually earliest date first.
  • Use date for calendar-day problems and switch carefully if the input is timestamp-based.

Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms