İki dizi verildiğinde; $births
birinin doğduğunu gösteren doğum yıllarının $deaths
listesini ve birinin öldüğünü gösteren ölüm yıllarının listesini içeren, nüfusun en yüksek olduğu yılı nasıl bulabiliriz?
Örneğin, aşağıdaki diziler verildiğinde:
$births = [1984, 1981, 1984, 1991, 1996];
$deaths = [1991, 1984];
Nüfusun en yüksek olduğu yıl olmalıdır 1996
, çünkü 3
insanlar o yıl boyunca yaşıyorlardı, ki bu o yılların en yüksek nüfus sayısıydı.
İşte çalışan matematik:
| Doğum | Ölüm | Nüfus | | ------- | ------- | ------------ | | 1981 | | 1 | | 1984 | | 2 | | 1984 | 1984 | 2 | | 1991 | 1991 | 2 | | 1996 | | 3 |
Varsayımlar
Birinin doğduğu yılın nüfusu bir artabileceğini ve birisinin öldüğü yılın nüfusu bir azaltabileceğini rahatlıkla söyleyebiliriz. Bu örnekte, 1984'te 2 kişi doğdu ve 1984'te 1 kişi öldü, yani nüfus o yıl 1 oranında arttı.
Ayrıca, ölüm sayısının asla doğum sayısını geçmeyeceğini ve nüfus 0 olduğunda ölüm meydana gelemeyeceğini rahatlıkla söyleyebiliriz.
Ayrıca, her ikisindeki yılların $deaths
ve $births
asla negatif veya kayan nokta değerleri olmayacağını varsayabiliriz ( her zaman 0'dan büyük pozitif tamsayılardır ).
Biz olamaz diziler sıralanmış olacak ya Ancak çift değer olmayacağını varsayıyorum.
Gereksinimler
Girdi olarak bu iki dizi göz önüne alındığında, en yüksek nüfusun meydana geldiği yılı döndürmek için bir işlev yazmalıyız. İşlev döndürebilir 0
, false
, ""
ya da NULL
( bir Falsey değer kabul edilebilir ) giriş dizileri boş ise ya da nüfus boyunca 0 ° C'de her zaman ise. En yüksek nüfus birden çok yılda meydana gelirse, işlev en yüksek nüfusa ulaşılan ilk yılı veya daha sonraki bir yılı döndürebilir.
Örneğin:
$births = [1997, 1997, 1997, 1998, 1999];
$deaths = [1998, 1999];
/* The highest population was 3 on 1997, 1998 and 1999, either answer is correct */
Ek olarak, çözümün Big O'su dahil olmak da yardımcı olacaktır.
Bunu yapmak için en iyi girişimim şöyle olurdu:
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 yukarıdaki o en kötü olduğu Verilen polinom zamanda çalışması gerekir O(((n log n) * 2) + k)
nerede n
unsurların sayısı her diziden sıralanıp edilecek olan k
(doğum yıl sayısıdır bunu biliyoruz çünkü k
her zamank >= y
olduğu) y
ölüm yıl sayısıdır. Ancak, daha verimli bir çözüm olup olmadığından emin değilim.
İlgi alanlarım , mevcut algoritma üzerinde gelişmiş bir hesaplama karmaşıklığı Big O'sunda. Bellek karmaşıklığı endişe vermez. Çalışma zamanı optimizasyonu da değildir. En azından birincil bir endişe değil . Herhangi bir küçük / büyük çalışma zamanı optimizasyonu açıktır, ancak burada anahtar faktör değildir.