Gegeben zwei Arrays; $births
eine Liste der Geburtsjahre enthält , die anzeigen , wenn jemand geboren wurde, und $deaths
eine Liste der Tod Jahren enthält , die anzeigen , wenn jemand gestorben ist , wie können wir das Jahr , an dem die Bevölkerung am höchsten war finden?
Zum Beispiel bei folgenden Arrays:
$births = [1984, 1981, 1984, 1991, 1996];
$deaths = [1991, 1984];
Das Jahr, in dem die Bevölkerung am höchsten war, sollte sein 1996
, da die 3
Menschen in diesem Jahr am Leben waren, was die höchste Bevölkerungszahl aller Jahre war.
Hier ist die laufende Mathematik dazu:
| Geburt | Tod | Bevölkerung | | ------- | ------- | ------------ | | 1981 | | 1 | | 1984 | | 2 | | 1984 | 1984 | 2 | | 1991 | 1991 | 2 | | 1996 | | 3 |
Annahmen
Wir können mit Sicherheit davon ausgehen, dass das Jahr, in dem jemand geboren wird, um eins zunehmen kann und das Jahr, in dem jemand stirbt, um eins zunehmen kann. In diesem Beispiel wurden 1984 2 Personen geboren und 1 Person starb 1984, was bedeutet, dass die Bevölkerung in diesem Jahr um 1 zunahm.
Wir können auch davon ausgehen, dass die Anzahl der Todesfälle niemals die Anzahl der Geburten überschreiten wird und dass kein Tod eintreten kann, wenn die Bevölkerung bei 0 liegt.
Wir können auch davon ausgehen, dass die Jahre in beiden $deaths
und $births
niemals negative oder Gleitkommawerte sind ( sie sind immer positive ganze Zahlen größer als 0 ).
Wir können jedoch nicht davon ausgehen, dass die Arrays sortiert werden oder dass es keine doppelten Werte gibt.
Bedarf
Wir müssen eine Funktion schreiben, um das Jahr zurückzugeben, in dem die höchste Population aufgetreten ist, wenn diese beiden Arrays als Eingabe verwendet werden. Die Funktion kann zurückkehren 0
, false
, ""
, oder NULL
( jeder Wert akzeptabel Falsey ) , wenn die Eingabefelder leer sind oder wenn die Bevölkerung immer bei 0 gänzlich. Wenn die höchste Bevölkerung in mehreren Jahren aufgetreten ist, kann die Funktion das erste Jahr, in dem die höchste Bevölkerung erreicht wurde, oder ein nachfolgendes Jahr zurückgeben.
Zum Beispiel:
$births = [1997, 1997, 1997, 1998, 1999];
$deaths = [1998, 1999];
/* The highest population was 3 on 1997, 1998 and 1999, either answer is correct */
Darüber hinaus wäre es hilfreich , das Big O der Lösung einzubeziehen.
Mein bester Versuch, dies zu tun, wäre der folgende:
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;
}
Der obige Algorithmus sollte gegeben in Polynomzeit arbeiten ist es im schlimmsten Fall , O(((n log n) * 2) + k)
wo n
ist die Anzahl der Elemente von jedem Array sortiert werden und k
ist die Anzahl der Geburt Jahre ( da wissen wir, dass k
es immerk >= y
) , wo y
Zahl der Todes Jahre. Ich bin mir jedoch nicht sicher, ob es eine effizientere Lösung gibt.
Mein Interesse gilt lediglich einem verbesserten Big O der Rechenkomplexität gegenüber dem vorhandenen Algorithmus. Die Speicherkomplexität spielt keine Rolle. Auch die Laufzeitoptimierung ist nicht. Zumindest ist es kein Hauptanliegen . Kleinere / größere Laufzeitoptimierungen sind willkommen, aber hier nicht der Schlüsselfaktor.