Étant donné deux tableaux; $births
contenant une liste des années de naissance indiquant quand quelqu'un est né, et $deaths
contenant une liste des années de décès indiquant quand quelqu'un est décédé, comment pouvons-nous trouver l'année où la population était la plus élevée?
Par exemple, étant donné les tableaux suivants:
$births = [1984, 1981, 1984, 1991, 1996];
$deaths = [1991, 1984];
L'année où la population était la plus élevée devrait être 1996
, car les 3
gens étaient en vie au cours de cette année, qui était le nombre de personnes le plus élevé de toutes ces années.
Voici les calculs en cours à ce sujet:
| Naissance | La mort | Population | | ------- | ------- | ------------ | | 1981 | | 1 | | 1984 | | 2 | | 1984 | 1984 | 2 | | 1991 | 1991 | 2 | | 1996 | | 3 |
Hypothèses
Nous pouvons supposer avec certitude que l'année de naissance d'une personne, la population peut augmenter d'une unité et l'année de décès d'une personne, la population peut diminuer d'une unité. Ainsi, dans cet exemple, 2 personnes sont nées en 1984 et 1 personne est décédée en 1984, ce qui signifie que la population a augmenté de 1 cette année-là.
Nous pouvons également supposer en toute sécurité que le nombre de décès ne dépassera jamais le nombre de naissances et qu'aucun décès ne peut survenir lorsque la population est à 0.
Nous pouvons également supposer en toute sécurité que les années dans les deux $deaths
et $births
ne seront jamais des valeurs négatives ou à virgule flottante ( ce sont toujours des entiers positifs supérieurs à 0 ).
Nous ne pouvons cependant pas supposer que les tableaux seront triés ou qu'il n'y aura pas de valeurs en double, cependant.
Exigences
Nous devons écrire une fonction pour retourner l'année où la population la plus élevée s'est produite, étant donné ces deux tableaux en entrée. La fonction peut retourner 0
, false
, ""
, ou NULL
( toute valeur de Falsey est acceptable ) si les tableaux d'entrée sont vides ou si la population était toujours à 0 ° C tout au long. Si la population la plus élevée s'est produite sur plusieurs années, la fonction peut renvoyer la première année au cours de laquelle la population la plus élevée a été atteinte ou toute année suivante.
Par exemple:
$births = [1997, 1997, 1997, 1998, 1999];
$deaths = [1998, 1999];
/* The highest population was 3 on 1997, 1998 and 1999, either answer is correct */
De plus, l'inclusion du Big O de la solution serait utile.
Ma meilleure tentative pour ce faire serait la suivante:
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;
}
L'algorithme ci-dessus devrait fonctionner en temps polynomial étant donné qu'il est au pire O(((n log n) * 2) + k)
où n
est le nombre d'éléments à trier de chaque tableau et k
est le nombre d'années de naissance ( car nous savons que k
c'est toujoursk >= y
) où y
est le nombre d'années de décès. Cependant, je ne sais pas s'il existe une solution plus efficace.
Mes intérêts sont purement dans un Big O amélioré de complexité de calcul sur l'algorithme existant. La complexité de la mémoire n'est pas un problème. L'optimisation de l'exécution n'est pas non plus. Au moins, ce n'est pas une préoccupation principale . Toutes les optimisations d'exécution mineures / majeures sont les bienvenues, mais pas le facteur clé ici.