Diberikan dua array; $births
berisi daftar tahun kelahiran yang menunjukkan kapan seseorang dilahirkan, dan $deaths
berisi daftar tahun kematian yang menunjukkan kapan seseorang meninggal, bagaimana kita dapat menemukan tahun di mana populasi tertinggi?
Misalnya diberikan array berikut:
$births = [1984, 1981, 1984, 1991, 1996];
$deaths = [1991, 1984];
Tahun di mana populasi tertinggi seharusnya 1996
, karena 3
orang-orang hidup selama tahun itu, yang merupakan jumlah populasi tertinggi sepanjang tahun itu.
Inilah perhitungannya:
| Kelahiran | Kematian | Populasi | | ------- | ------- | ------------ | | 1981 | | 1 | | 1984 | | 2 | | 1984 | 1984 | 2 | | 1991 | 1991 | 2 | | 1996 | | 3 |
Asumsi
Kita dapat dengan aman berasumsi bahwa tahun di mana seseorang dilahirkan populasi dapat meningkat satu dan tahun di mana seseorang meninggal populasi dapat berkurang satu. Jadi, dalam contoh ini, 2 orang lahir pada tahun 1984 dan 1 orang meninggal pada tahun 1984, artinya populasi meningkat 1 pada tahun itu.
Kita juga dapat dengan aman berasumsi bahwa jumlah kematian tidak akan pernah melebihi jumlah kelahiran dan bahwa tidak ada kematian dapat terjadi ketika populasi berada pada 0.
Kita juga dapat dengan aman mengasumsikan bahwa tahun-tahun di keduanya $deaths
dan $births
tidak akan pernah menjadi nilai negatif atau floating point ( mereka selalu bilangan bulat positif lebih besar dari 0 ).
Kami tidak dapat berasumsi bahwa array akan diurutkan atau tidak akan ada nilai duplikat.
Persyaratan
Kita harus menulis fungsi untuk mengembalikan tahun di mana populasi tertinggi terjadi, mengingat dua array ini sebagai input. Fungsi dapat kembali 0
, false
, ""
, atau NULL
( nilai apapun falsey diterima ) jika array masukan kosong atau jika populasi selalu pada 0 seluruh. Jika populasi tertinggi terjadi pada beberapa tahun, fungsi dapat mengembalikan tahun pertama di mana populasi tertinggi dicapai atau tahun berikutnya.
Sebagai contoh:
$births = [1997, 1997, 1997, 1998, 1999];
$deaths = [1998, 1999];
/* The highest population was 3 on 1997, 1998 and 1999, either answer is correct */
Selain itu, termasuk Big O dari solusi akan sangat membantu.
Upaya terbaik saya untuk melakukan ini adalah sebagai berikut:
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;
}
Algoritma di atas harus bekerja dalam waktu polinomial mengingat paling buruk di O(((n log n) * 2) + k)
mana n
jumlah elemen yang akan diurutkan dari setiap array dan k
jumlah tahun kelahiran ( karena kita tahu itu k
selaluk >= y
) di mana y
jumlah tahun kematian. Namun, saya tidak yakin apakah ada solusi yang lebih efisien.
Minat saya murni pada perbaikan kompleksitas komputasi pada algoritma yang ada. Kompleksitas memori tidak menjadi masalah. Optimasi runtime juga tidak. Setidaknya itu bukan masalah utama . Semua optimasi runtime minor / utama disambut baik, tetapi bukan faktor kunci di sini.