给定两个数组;$births
包含表明某人出生的出生年份列表,以及$deaths
表明某人死亡的死亡年份列表,我们如何找到人口最高的年份?
例如,给定以下数组:
$births = [1984, 1981, 1984, 1991, 1996];
$deaths = [1991, 1984];
人口最高的年份应该是1996
,因为3
那一年人们还活着,这是所有年份中人口最高的年份。
这是运行的数学公式:
| 出生| 死亡 人口| | ------- | ------- | ------------ || | 1981年| | 1 | | 1984年| | 2 | | 1984年| 1984年| 2 | | 1991年| 1991年| 2 | | 1996 | | 3 |
假设条件
我们可以放心地假设某人出生的年份可以增加一,而某人死亡的年份可以减少一。因此,在此示例中,1984年出生2人,1984年死亡1人,这意味着该年人口增加了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
是死亡年数。但是,我不确定是否有更有效的解决方案。
我的兴趣纯粹是在现有算法的基础上改进计算复杂度。内存复杂性无关紧要。运行时优化也不是。至少这不是主要问题。欢迎进行任何次要/主要的运行时优化,但这不是关键因素。