在某些列表中说我有以下范围:
{ (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)时间和恒定空间怎么样?感谢。
答案 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
是范围数。
按字典顺序对范围(a, b)
进行排序,方法是增加a
,然后减少b
。
Before: { (1, 4), (6, 8), (2, 5), (1, 3) }
After: { (1, 4), (1, 3), (2, 5), (6, 8) }
将已排序的范围序列折叠为可能更短的范围序列,如果(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) }
将范围序列映射到它们的大小。
Before: { (1, 5), (6, 8) }
After: { 5, 3 }
总结大小以得出总天数。
8