รับสองอาร์เรย์ $births
มีรายการปีเกิดแสดงเมื่อมีคนเกิดและ$deaths
มีรายการปีแห่งความตายที่ระบุเมื่อมีคนตายเราจะหาปีที่ประชากรสูงสุดได้อย่างไร
ตัวอย่างเช่นกำหนดอาร์เรย์ต่อไปนี้:
$births = [1984, 1981, 1984, 1991, 1996];
$deaths = [1991, 1984];
ปีที่ประชากรสูงสุดควรเป็น1996
เพราะ3
ประชาชนยังมีชีวิตอยู่ในช่วงปีนั้นซึ่งเป็นประชากรที่สูงที่สุดนับจากทุกปี
นี่คือคณิตศาสตร์ที่ใช้อยู่ในนั้น:
| เกิด | ความตาย | ประชากร | ------- | ------- | ------------ | | 1981 | | 1 | | 2527 | | 2 | | 2527 | 2527 | 2 | | 2534 | 2534 | 2 | | 2539 | | 3 |
สมมติฐาน
เราสามารถสรุปได้อย่างปลอดภัยว่าปีที่ใครบางคนเกิดมาประชากรสามารถเพิ่มขึ้นได้หนึ่งปีและปีที่บางคนเสียชีวิตประชากรสามารถลดลงได้หนึ่งคน ดังนั้นในตัวอย่างนี้ 2 คนเกิดในปี 1984 และอีก 1 คนเสียชีวิตในปี 1984 ซึ่งหมายความว่าจำนวนประชากรที่เพิ่มขึ้น 1 ในปีนั้น
เราสามารถสรุปได้อย่างปลอดภัยว่าจำนวนผู้เสียชีวิตจะไม่เกินจำนวนการเกิดและจะไม่มีการเสียชีวิตเกิดขึ้นเมื่อประชากรอยู่ที่ 0
เราสามารถสันนิษฐานได้อย่างปลอดภัยว่าหลายปีในทั้งสองนี้$deaths
และ$births
จะไม่เป็นค่าลบหรือทศนิยม ( พวกมันมักเป็นจำนวนเต็มบวกมากกว่า 0 )
เราไม่สามารถสรุปได้ว่าอาร์เรย์จะถูกเรียงลำดับหรือจะไม่มีค่าซ้ำกัน
ความต้องการ
เราจะต้องเขียนฟังก์ชั่นเพื่อคืนปีที่มีประชากรมากที่สุดเกิดขึ้นเนื่องจากทั้งสองอาร์เรย์เป็นอินพุต ฟังก์ชั่นอาจจะกลับมา0
, false
, ""
หรือNULL
( ค่า falsey ใด ๆ ที่เป็นที่ยอมรับได้ ) ถ้าอาร์เรย์การป้อนข้อมูลที่ว่างเปล่าหรือถ้าประชากรที่เป็นเสมอที่ 0 ตลอด หากจำนวนประชากรสูงสุดเกิดขึ้นในหลายปีฟังก์ชันอาจส่งคืนปีแรกที่มีจำนวนประชากรสูงถึงหรือในปีต่อ ๆ มา
ตัวอย่างเช่น:
$births = [1997, 1997, 1997, 1998, 1999];
$deaths = [1998, 1999];
/* The highest population was 3 on 1997, 1998 and 1999, either answer is correct */
นอกจากนี้รวมถึงBig Oของโซลูชันจะเป็นประโยชน์
ความพยายามที่ดีที่สุดของฉันในการทำเช่นนี้จะเป็นดังนี้:
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;
}
อัลกอริทึมด้านบนควรทำงานในเวลาพหุนามเนื่องจากมันแย่ที่สุดO(((n log n) * 2) + k)
โดยที่n
จำนวนขององค์ประกอบที่จะเรียงลำดับจากแต่ละอาร์เรย์และk
เป็นจำนวนปีเกิด ( เนื่องจากเรารู้ว่าk
เป็นเสมอk >= y
) โดยที่y
เป็นจำนวนปีการเสียชีวิต อย่างไรก็ตามฉันไม่แน่ใจว่ามีวิธีแก้ปัญหาที่มีประสิทธิภาพมากกว่านี้หรือไม่
ความสนใจของฉันล้วนๆในBig O ที่ปรับปรุงใหม่ของความซับซ้อนในการคำนวณตามอัลกอริทึมที่มีอยู่ ความซับซ้อนของหน่วยความจำไม่เกี่ยวข้อง ไม่เป็นการเพิ่มประสิทธิภาพรันไทม์ อย่างน้อยก็ไม่ได้เป็นความกังวลหลัก การปรับแต่งรันไทม์เล็กน้อย / หลักใด ๆ ยินดีต้อนรับ แต่ไม่ใช่ปัจจัยสำคัญที่นี่