Cho hai mảng; $births
chứa một danh sách các năm sinh cho biết khi ai đó được sinh ra và $deaths
chứa một danh sách các năm chết cho biết khi ai đó chết, làm thế nào chúng ta có thể tìm thấy năm mà dân số cao nhất?
Ví dụ cho các mảng sau:
$births = [1984, 1981, 1984, 1991, 1996];
$deaths = [1991, 1984];
Năm mà dân số cao nhất nên là 1996
bởi vì 3
mọi người còn sống trong năm đó, đó là số dân cao nhất trong tất cả các năm đó.
Đây là phép toán đang chạy trên đó:
| Sinh | Cái chết | Dân số | | ------- | ------- | ------------ | | 1981 | | 1 | | 1984 | | 2 | | 1984 | 1984 | 2 | | 1991 | 1991 | 2 | | 1996 | | 3 |
Giả định
Chúng ta có thể giả định một cách an toàn rằng năm mà một người nào đó được sinh ra, dân số có thể tăng thêm một và năm mà một người nào đó chết, dân số có thể giảm đi một. Vì vậy, trong ví dụ này, 2 người sinh năm 1984 và 1 người chết năm 1984, nghĩa là dân số tăng thêm 1 vào năm đó.
Chúng ta cũng có thể giả định một cách an toàn rằng số người chết sẽ không bao giờ vượt quá số ca sinh và không có trường hợp tử vong nào có thể xảy ra khi dân số ở mức 0.
Chúng ta cũng có thể giả định một cách an toàn rằng các năm ở cả hai $deaths
và $births
sẽ không bao giờ là giá trị âm hoặc dấu phẩy động ( chúng luôn là các số nguyên dương lớn hơn 0 ).
Chúng tôi không thể giả định rằng các mảng sẽ được sắp xếp hoặc tuy nhiên sẽ không có giá trị trùng lặp.
Yêu cầu
Chúng ta phải viết một hàm để trả về năm có dân số cao nhất xuất hiện, lấy hai mảng này làm đầu vào. Các chức năng có thể trở lại 0
, false
, ""
, hoặc NULL
( bất kỳ giá trị falsey là chấp nhận được ) nếu các mảng đầu vào là rỗng hoặc nếu dân số luôn ở mức 0 trong suốt. Nếu dân số cao nhất xảy ra trong nhiều năm, chức năng có thể trở lại vào năm đầu tiên mà dân số cao nhất đã đạt được hoặc bất kỳ năm tiếp theo nào.
Ví dụ:
$births = [1997, 1997, 1997, 1998, 1999];
$deaths = [1998, 1999];
/* The highest population was 3 on 1997, 1998 and 1999, either answer is correct */
Ngoài ra, bao gồm cả Big O của giải pháp sẽ hữu ích.
Nỗ lực tốt nhất của tôi trong việc này sẽ là như sau:
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;
}
Các thuật toán trên nên làm việc trong thời gian đa thức cho nó là lúc tồi tệ nhất O(((n log n) * 2) + k)
mà n
là số nguyên tố được sắp xếp từ từng mảng và k
là số năm sinh ( kể từ khi chúng ta biết rằng k
luônk >= y
), nơi y
là số năm cái chết. Tuy nhiên, tôi không chắc có giải pháp nào hiệu quả hơn không.
Sở thích của tôi hoàn toàn là một Big O cải tiến về độ phức tạp tính toán dựa trên thuật toán hiện có. Bộ nhớ phức tạp là không quan tâm. Cũng không phải là tối ưu hóa thời gian chạy. Ít nhất nó không phải là mối quan tâm chính . Bất kỳ tối ưu hóa thời gian chạy nhỏ / chính đều được chào đón, nhưng không phải là yếu tố chính ở đây.