Biorąc pod uwagę dwie tablice; $births
zawierający listę lat urodzenia wskazującą, kiedy ktoś się urodził, oraz $deaths
listę lat śmierci wskazującą, kiedy ktoś umarł, w jaki sposób możemy znaleźć rok, w którym populacja była najwyższa?
Na przykład biorąc pod uwagę następujące tablice:
$births = [1984, 1981, 1984, 1991, 1996];
$deaths = [1991, 1984];
Powinien być rok, w którym populacja była najwyższa 1996
, ponieważ 3
ludzie żyli w tym roku, który był najwyższą liczbą ludności we wszystkich tych latach.
Oto bieżąca matematyka na ten temat:
| Narodziny | Śmierć | Ludność | | ------- | ------- | ------------ | | 1981 | | 1 | | 1984 | | 2 | | 1984 | 1984 | 2 | | 1991 | 1991 | 2 | | 1996 | | 3 |
Założenia
Możemy bezpiecznie założyć, że rok, w którym ktoś się urodzi, populacja może wzrosnąć o jeden rok, a rok, w którym ktoś umrze, populacja może się zmniejszyć o jeden. W tym przykładzie 2 osoby urodziły się w 1984 r., A 1 osoba zmarła w 1984 r., Co oznacza, że liczba ludności wzrosła o 1 w tym roku.
Możemy również bezpiecznie założyć, że liczba zgonów nigdy nie przekroczy liczby urodzeń i że śmierć nie może wystąpić, gdy populacja wynosi 0.
Możemy również bezpiecznie założyć, że lata w obu przypadkach $deaths
i $births
nigdy nie będą wartościami ujemnymi lub zmiennoprzecinkowymi ( zawsze są dodatnimi liczbami całkowitymi większymi niż 0 ).
Nie możemy jednak zakładać, że tablice zostaną posortowane lub że nie będzie zduplikowanych wartości.
Wymagania
Musimy napisać funkcję zwracającą rok, w którym wystąpiła najwyższa populacja, biorąc pod uwagę te dwie tablice jako dane wejściowe. Funkcja może powrócić 0
, false
, ""
lub NULL
( każda wartość falsey jest dopuszczalna ), gdy tablice wejściowe są puste czy populacja zawsze w 0 ° C przez cały czas. Jeśli najwyższa populacja występowała przez wiele lat, funkcja może powrócić do pierwszego roku, w którym osiągnięto najwyższą populację, lub dowolnego następnego roku.
Na przykład:
$births = [1997, 1997, 1997, 1998, 1999];
$deaths = [1998, 1999];
/* The highest population was 3 on 1997, 1998 and 1999, either answer is correct */
Dodatkowo pomocne byłoby włączenie Big O rozwiązania.
Moja najlepsza próba zrobienia tego to:
function highestPopulationYear(Array $births, Array $deaths): Int {
sort($births);
sort($deaths);
$nextBirthYear = reset($births);
$nextDeathYear = reset($deaths);
$years = [];
if ($nextBirthYear) {
$years[] = $nextBirthYear;
}
if ($nextDeathYear) {
$years[] = $nextDeathYear;
}
if ($years) {
$currentYear = max(0, ...$years);
} else {
$currentYear = 0;
}
$maxYear = $maxPopulation = $currentPopulation = 0;
while(current($births) !== false || current($deaths) !== false || $years) {
while($currentYear === $nextBirthYear) {
$currentPopulation++;
$nextBirthYear = next($births);
}
while($currentYear === $nextDeathYear) {
$currentPopulation--;
$nextDeathYear = next($deaths);
}
if ($currentPopulation >= $maxPopulation) {
$maxPopulation = $currentPopulation;
$maxYear = $currentYear;
}
$years = [];
if ($nextBirthYear) {
$years[] = $nextBirthYear;
}
if ($nextDeathYear) {
$years[] = $nextDeathYear;
}
if ($years) {
$currentYear = min($years);
} else {
$currentYear = 0;
}
}
return $maxYear;
}
Powyższy algorytm powinien działać w czasie wielomianowym, biorąc pod uwagę, że w najgorszym O(((n log n) * 2) + k)
przypadku n
jest to liczba elementów do posortowania z każdej tablicy i k
liczba lat urodzenia ( ponieważ wiemy, że tak k
jest zawszek >= y
), gdzie y
jest liczba lat śmierci. Nie jestem jednak pewien, czy istnieje bardziej wydajne rozwiązanie.
Moje zainteresowania skupiają się wyłącznie na ulepszonym Big O złożoności obliczeniowej w stosunku do istniejącego algorytmu. Złożoność pamięci nie ma znaczenia. Nie jest też optymalizacja środowiska wykonawczego. Przynajmniej nie jest to główny problem . Wszelkie drobne / większe optymalizacje środowiska wykonawczego są mile widziane, ale nie są to kluczowe czynniki.