두 개의 배열이 주어진다; $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 |
가정
우리는 누군가가 태어난 해가 1 년 증가 할 수 있고 누군가가 사망 한 해가 1 감소 할 수 있다고 안전하게 가정 할 수 있습니다. 이 예에서 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
. 그러나 더 효율적인 솔루션이 있는지 확실하지 않습니다.
내 관심은 순전히 기존 알고리즘에 대한 계산 복잡성 의 개선 된 Big O에 있습니다. 메모리 복잡도는 중요하지 않습니다. 런타임 최적화도 아닙니다. 적어도 그것은 주요 관심사가 아닙니다 . 사소한 / 주요 런타임 최적화는 환영하지만 여기서 중요한 요소는 아닙니다.