从一组范围中查找最常见的数字 -

时间:2012-12-30 16:49:10

标签: algorithm computational-geometry

问题如下: -

您将获得N个不同大象的生命时间,表示为一对整数。

离。 [5,10] [6,15] [2,7] 意思是,一头大象从5年级到10年级。第二年大学从6年级到15年级,依此类推。

你可能认为大象最多只能活M年。 (不是问题的一部分,但我们可能需要它来表示算法的复杂性。)

根据这些数据,找到最大数量的大象生活年份。 任意解决关系。

我已经尝试了几种方法,但没有任何实质性的东西可以打败天真的解决方案的复杂性。天真的解决方案是: -

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.

很容易看出复杂性为O(N * M)。

有人能提供更好的解决方案吗?

另一个问题是:是否存在可以在O(1)时间内更改值范围的数据结构?在数组中,要修改k个元素,您显然需要O(k)时间。还有什么更好的吗?

2 个答案:

答案 0 :(得分:6)

将范围的左端视为+1大象活着,并将范围的右端视为-1大象活着。将这些+1和-1标记放在数字行上,然后在数字行上从左到右按顺序排列。当您走数字线时,跟踪当前活着的大象数量(只需加上+1和-1),然后根据活着的大象和相应的年份来检查它。然后你有一个很好的O(n log n)时间解决问题的方法。

请注意,您必须要小心谨慎才能在当前年份的+1之前处理-1s,或者仅在处理给定年份内的所有数据后更新最大值。

答案 1 :(得分:2)

以下是基于@rrenaud's answer的Python中"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)