Explic întâi logica vizual, și apoi postez și cod.
Pentru a ne asigura că ajungem la rezultatul corect, o să facem exemplul lor puțin mai complicat, așa încât să luăm în calcul și cerința “there might be more than one meeting at any given time.”. Așadar, o să folosesc pentru ilustrație exemplul:
[(0, 1), (3, 5), (4, 8), (10, 12), (4, 7), (9, 10)]
Observă cum între 4 și 7 sunt două întâlniri simultane.
- Sortăm întâlnirile după ora de început, crescător, iar apoi după ora de sfârșit, tot crescător: https://i.imgur.com/6WZcV5L.png
- Un timeslot e liber numai atunci când data de sfârșit a unei întâlniri este anterioară datei de început a celei care urmează imediat după: https://i.imgur.com/eYHq6VB.png
Vizual e foarte clar, să trecem la implementare. O să implementez în JS, deși chiar nu are nici o importanță, la fel de bine poți explica algoritmul în orice limbaj:
function getTimeslots(meetings) {
meetings.sort(function (a, b) {
if (a[0] < b[0]) {
return -1;
} else if (a[0] > b[0]) {
return 1;
} else {
if (a[1] < b[1]) {
return -1;
} else {
return 1;
}
}
});
var timeslots = [], current, next;
for (var i = 0; i < meetings.length - 1; i++) {
current = meetings[i];
next = meetings[i + 1];
if (current[1] < next[0]) {
timeslots.push([current[1], next[0]]);
}
}
return timeslots;
}
var tests = {total: 0, passed: 0, failed: 0};
function check(meetings, expected) {
tests.total++;
var timeslots = getTimeslots(meetings);
if (timeslots.toString() == expected.toString()) {
tests.passed++;
} else {
tests.failed++;
console.error("Expected: " + JSON.stringify(expected) + ". Got: " + JSON.stringify(timeslots));
}
}
check(
[[0, 1], [3, 5], [4, 8], [10, 12], [4, 7], [9, 10]],
[[1, 3], [8, 9]]
);
console.log(tests);
Poți să apelezi funcția check()
cu mai multe variante de meetings, pentru a testa. Eu nu am testat cu foarte multe variante, deci nu garantez 100% corectitudinea.
Observație: Este important să sortăm după ambele capete ale unui meeting, pentru că altfel nu am putea respecta cerința cu meeting-urile care se suprapun. Dacă am sorta numai după ora de început, am avea următoarea situație: https://i.imgur.com/7mAZxZs.png. Observă cum am considera (7, 9)
ca timeslot liber, în loc de (8, 9)
.