SQL knows how to sort stuff, and I'd bet your engine uses the most efficient algorithm it can (i.e. O(n log(n))
), while still working if the result set doesn't fit in RAM (in contrast with K.Steff's answer which will fail if the array doesn't fit in RAM). In python :
import sqlite3
connection = sqlite3.connect("database.db")
cursor = connection.cursor()
cursor.execute("SELECT isStart from (" +
" SELECT startTime AS time, 1 AS isStart FROM myTable " +
" UNION ALL " +
" SELECT endTime as time, -1 AS isStart FROM myTable " +
" ORDER BY time ASC, isStart ASC" +
")")
maxOverlap = 0
currentOverlap = 0
for (isStart,) in cursor:
currentOverlap += isStart
maxOverlap = max(maxOverlap, currentOverlap)
print maxOverlap
Note the isStart ASC
order is necessary so the intervals [10,15]
and [15,23]
are not considered overlapping.
For further improvement, it is probably the case that the columns startTime and endTime have an index, so the SQL engine should efficiently merge the two already sorted tables, resulting in an O(n)
operation (the O(log(n))
factor then happens at insertion time for each row, when it is added to the index, but you already have it anyway). If your SQL engine isn't smart enough to do an efficient merge, do it yourself on the fly (still in python) :
import sqlite3
connection = sqlite3.connect("database.db")
cursorStart = connection.cursor()
cursorStart.execute("SELECT startTime FROM myTable ORDER BY startTime ASC")
cursorEnd = connection.cursor()
cursorEnd.execute("SELECT endTime FROM myTable ORDER BY endTime ASC")
maxOverlap = 0
currentOverlap = 0
currentStart = cursorStart.fetchone()
currentEnd = cursorEnd.fetchone()
while currentStart is not None and currentEnd is not None:
if currentStart < currentEnd:
currentOverlap += 1
currentStart = cursorStart.fetchone()
else:
currentOverlap -= 1
currentEnd = cursorEnd.fetchone()
maxOverlap = max(maxOverlap, currentOverlap)
print maxOverlap