根据日间范围的集合计算天数?

时间:2014-09-17 00:53:38

标签: algorithm

在某些列表中说我有以下范围:

{ (1, 4), (6, 8), (2, 5), (1, 3) }

(1, 4)代表第1,2,3,4天。(6, 8)代表第6天,第7天,第8天等等。

目标是找到范围集合中列出的总天数 - 例如,在上面的示例中,答案为8,因为第1,2,3,4,6,7天,8和5包含在范围内。

通过迭代每个范围中的日期并将它们放入HashSet,然后返回HashSet的大小,可以轻松解决此问题。但是有没有办法在O(n)时间内对范围对的数量做?在O(n)时间和恒定空间怎么样?感谢。

2 个答案:

答案 0 :(得分:1)

按范围的下限按升序对范围进行排序。你可以在线性时间内完成这个,因为你正在处理整数。

其余的很容易。一旦跟踪numDays(初始化为零)和maximumDay(初始化为-INF),循环遍历范围。在达到每个间隔(a,b)时:

如果b>那时最大的 numDays< - numDays + b-max(a - 1,largestDay) maximumDay< - max(largestDay,b)

别无其他。


因此,在分选后我们有(1,4),(1,3),(2,5),(6,8)

(1,4):numDays< - 0 +(4 - max(1 - 1,-INF))= 4,maximumDay< - max(-INF,4)= 4

(1,3):b<最大的日子,所以没有变化。

(2,5):numDays< - 4 +(5 - max(2 - 1,4))= 5,maximumDay< - 5

(6,8):numDays< - 5 +(8 - max(6-1,5))= 8,largestDay< -8

答案 1 :(得分:0)

以下算法的复杂性为O(n log n),其中n是范围数。

  1. 按字典顺序对范围(a, b)进行排序,方法是增加a,然后减少b

    Before: { (1, 4), (6, 8), (2, 5), (1, 3) }
    After:  { (1, 4), (1, 3), (2, 5), (6, 8) }
    
  2. 将已排序的范围序列折叠为可能更短的范围序列,如果(a, b),则将连续的(c, d)(a, max(b, d))重复合并到b >= c

    Before: { (1, 4), (1, 3), (2, 5), (6, 8) }
            { (1, 4), (2, 5), (6, 8) }
    After:  { (1, 5), (6, 8) }
    
  3. 将范围序列映射到它们的大小。

    Before: { (1, 5), (6, 8) }
    After:  { 5, 3 }
    
  4. 总结大小以得出总天数。

    8