4

The question is as follows:-

You are given the life time of N different elephants, represented as a pair of integers.

ex. [5,10] [6,15] [2,7] means, one elephant lived from Year 5 to Year 10. The second lived from Year 6 to Year 15 and so on..

You may assume that an elephant can only live a maximum of M years. (Not a part of the question, but we may need it to represent algorithmic complexity.)

Given this data, find the year in which the maximum number of elephants lived. Resolve ties arbitrarily.

I have tried several approaches to this, but nothing substantial seems to beat the naive solution's complexity. The naive solution is:-

1. Maintain an array(call it ctr).
2. For every set you encounter, 
    increment all values of ctr in that range.
3. Once you have traversed all sets, 
    find the index with the highest value in ctr.

It's easy to see that the complexity will be O(N*M).

Can anyone offer a better solution?

An alternative question is: Is there a data structure in which you can change a range of values in O(1) time? In an array, to modify k elements, you clearly require O(k) time. Anything better?

Rob Neuhaus
  • 9,190
  • 3
  • 28
  • 37
Kanishk
  • 167
  • 7

2 Answers2

9

Think of the left end of a range as +1 elephant alive, and the right end of range as -1 elephant alive. Put those +1 and -1 markers on a number line, and then go in sorted order from left to right on the number line. As you walk the number line, keep track of current number of elephants alive (just add up the +1 and -1s), and check it against the maximum number of elephants alive and corresponding year. Then you have a nice O(n log n) time solution to the problem.

Note that you have to be a little careful with the bookkeeping to handle -1s before +1s in the current year, or only to update your maximums after you process all the data within a given year.

Rob Neuhaus
  • 9,190
  • 3
  • 28
  • 37
  • :Why do we need to go in a sorted order? Can't we put the +1s and -1s as they appear in the array, and then traverse our new ctr array. – Kanishk Dec 30 '12 at 17:27
  • 1
    I've posted [implementation in Python of your solution](http://stackoverflow.com/a/14093478/4279) – jfs Dec 30 '12 at 19:10
2

Here's an implementatin of @rrenaud's answer in Python based on "scan line" trick:

#!/usr/bin/env python
ranges = [5,10], [6,15], [2,7]

BORN, DIE = 1, 0 # values define sorting order within the same year
events = sorted(event # sort start 'born' and end 'die' events together by year,
                      # process 'die' before 'born' in the same year
                for r in ranges  for event in zip(r, (BORN, DIE)))

max_nelephants = nelephants = 0
prev_year = events[0][0]
for year, born_or_die in events:
    if prev_year != year: # done processing a year
        prev_year = year
        max_nelephants = max(max_nelephants, nelephants)
    nelephants += (born_or_die == BORN) # increase number of alive elephants
    nelephants -= (born_or_die == DIE)  # decrease number of alive elephants
max_nelephants = max(max_nelephants, nelephants)
print(max_nelephants)
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670