AlgoMaster Logo

Maximum Population Year

Last Updated: March 29, 2026

easy

Understanding the Problem

We have a list of people, each with a birth year and a death year. A person is alive during any year from their birth year up to (but not including) their death year. We need to find which year had the most people alive, and if there's a tie, return the earliest such year.

The key detail to notice is the half-open interval: a person born in 1993 who dies in 1999 is alive during years 1993, 1994, 1995, 1996, 1997, and 1998, but NOT 1999. This "alive during [birth, death - 1]" rule is the kind of off-by-one detail that trips people up, so it's worth nailing down before writing any code.

The year range is also very small: 1950 to 2050, which is only 101 possible years. That small range is a strong hint that we can afford to check every year individually or use a fixed-size array to track populations.

Key Constraints:

  • 1 <= logs.length <= 100 → At most 100 people. Even an O(n * Y) brute force where Y is the year range (101 years) means about 10,000 operations. Anything works here.
  • 1950 <= birthi < deathi <= 2050 → The year range is fixed and tiny (101 years). We can use a fixed-size array indexed by year. This also guarantees every person is alive for at least one year.

Approach 1: Brute Force (Check Every Year)

Intuition

The simplest way to think about this: for each possible year in the range [1950, 2050], count how many people are alive. A person is alive in year y if birth <= y < death. Track which year has the highest count, and return the earliest one in case of ties.

Since the year range is tiny (101 years) and the number of people is small (at most 100), this nested loop is perfectly fine. It's the approach most people would naturally think of first, and it directly translates the problem statement into code.

Algorithm

  1. Initialize maxPopulation = 0 and resultYear = 0.
  2. For each year y from 1950 to 2050:
    • Count how many people have birth <= y and death > y.
    • If this count is greater than maxPopulation, update maxPopulation and set resultYear = y.
  3. Return resultYear.

Example Walkthrough

1Year 1950: Check each person's lifespan
[1950, 1961]
[1960, 1971]
[1970, 1981]
19501981
1/6

Code

This approach works but redundantly checks each person for every year. What if we recorded only the boundary events and swept through them once?

Approach 2: Line Sweep (Difference Array)

Intuition

Instead of counting the population year by year, think of each person as creating two events: a birth (population goes up by 1) and a death (population goes down by 1). If we record these events in an array and then sweep from left to right, accumulating the changes, the running total at each year gives us the population for that year.

This is the line sweep or difference array technique. It's one of the most useful patterns in competitive programming and interviews. The idea is simple: rather than updating every year in a person's lifespan, we only mark where changes happen (the boundaries), and then compute the cumulative effect in a single pass.

For this problem, we create an array of size 101 (covering years 1950 through 2050). For each person with birth year b and death year d, we do +1 at index b - 1950 and -1 at index d - 1950. Then a prefix sum over this array gives the population at each year.

Algorithm

  1. Create an integer array delta of size 101 (years 1950 to 2050), initialized to zeros.
  2. For each person [birth, death] in logs:
    • Increment delta[birth - 1950] by 1 (a person starts being alive).
    • Decrement delta[death - 1950] by 1 (a person stops being alive).
  3. Sweep left to right, maintaining a running sum. At each year, the running sum is the population.
  4. Track the maximum population and the earliest year that achieves it.
  5. Return that year.

Example Walkthrough

1Initialize delta array (showing indices 0-31 for years 1950-1981)
0
0
1
0
2
0
3
0
4
0
5
0
6
0
7
0
8
0
9
0
10
0
11
0
12
0
13
0
14
0
15
0
16
0
17
0
18
0
19
0
20
0
21
0
22
0
23
0
24
0
25
0
26
0
27
0
28
0
29
0
30
0
31
0
1/8

Code