Dati due array; $birthscontenente un elenco di anni di nascita che indica quando è nato qualcuno e $deathsun elenco di anni di morte che indica quando qualcuno è morto, come possiamo trovare l'anno in cui la popolazione era più alta?
Ad esempio, dati i seguenti array:
$births = [1984, 1981, 1984, 1991, 1996];
$deaths = [1991, 1984];
L'anno in cui la popolazione era più alta dovrebbe essere 1996, perché la 3gente era viva durante quell'anno, che era il conteggio della popolazione più alta di tutti quegli anni.
Ecco la matematica corrente su questo:
| Nascita | Morte | Popolazione | | ------- | ------- | ------------ | | 1981 | | 1 | | 1984 | | 2 | | 1984 | 1984 | 2 | | 1991 | 1991 | 2 | | 1996 | | 3 |
ipotesi
Possiamo tranquillamente supporre che l'anno in cui qualcuno nasce la popolazione può aumentare di uno e l'anno in cui qualcuno è morto la popolazione può diminuire di uno. Quindi, in questo esempio, 2 persone sono nate nel 1984 e 1 persona è morta nel 1984, il che significa che la popolazione è aumentata di 1 in quell'anno.
Possiamo anche presumere che il numero di decessi non supererà mai il numero di nascite e che nessuna morte può verificarsi quando la popolazione è a 0.
Possiamo anche presumere che gli anni in entrambi $deathse $birthsnon saranno mai valori negativi o in virgola mobile ( sono sempre numeri interi positivi maggiori di 0 ).
Non possiamo supporre che gli array saranno ordinati o che non ci saranno valori duplicati, tuttavia.
Requisiti
Dobbiamo scrivere una funzione per restituire l'anno in cui si è verificata la popolazione più elevata, dati questi due array come input. La funzione può restituire 0, false, ""o NULL( qualsiasi valore falsey è accettabile ) se gli array in input sono vuote o se la popolazione era sempre a 0 in tutto. Se la popolazione più elevata si è verificata in più anni, la funzione può restituire il primo anno in cui è stata raggiunta la popolazione più elevata o qualsiasi anno successivo.
Per esempio:
$births = [1997, 1997, 1997, 1998, 1999];
$deaths = [1998, 1999];
/* The highest population was 3 on 1997, 1998 and 1999, either answer is correct */
Inoltre, includere la Big O della soluzione sarebbe utile.
Il mio miglior tentativo di farlo sarebbe il seguente:
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'algoritmo sopra dovrebbe funzionare nel tempo polinomiale dato che è nel peggiore dei casi O(((n log n) * 2) + k)dove nè il numero di elementi da ordinare da ciascun array ed kè il numero di anni di nascita ( poiché sappiamo che kè semprek >= y ) dove yè il numero di anni di morte. Tuttavia, non sono sicuro che esista una soluzione più efficiente.
I miei interessi sono puramente in una Big O migliorata di complessità computazionale sull'algoritmo esistente. La complessità della memoria non è preoccupante. Né è l'ottimizzazione del runtime. Almeno non è una preoccupazione primaria . Eventuali ottimizzazioni di runtime minori / maggiori sono benvenute, ma non il fattore chiave qui.