Your intersection code only catches cases where a meeting is entirely within the time of another meeting. For example, it will not catch the overlap in 10am-2pm and 1pm-4pm. Instead, its easier to check for non-intersection, and then negate. This is a popular approach to checking for intersection in rectangles.
if (!(item.StartTime > other.endTime || otheritem.endTime < itemother.StartTime)) {
// overlap
}
As others have mentioned the algorithmic improvement is to use a merge to get O(M + N) complexity. The tricky part is that you compare the ends of the meeting times to decide which to advance.
Imagine one list with 1 all day meeting and the other with meetings every hour. The first overlaps works just fine, but the all day meeting started first and if you advance that list your search is ended prematurely.
If you advance the list which has the earlier ending meeting you will be fine since that meeting ends before the other list's next item starts, you won't miss any overlaps.
int meet1 = 0;
int meet2 = 0;
while (meet1 < list1.Count && meet2 < list2.Count) {
if (intersects(list1[meet1], list2[meet2]) {
// add to list
}
if (list1[meet1].endTime < list2[meet2].endTime) {
++meet1;
} else {
++meet2;
}
}
(feel free to edit and flesh this out)