This problem can be solved easily and efficiently using binary search (which works in O (log n), faster than linear search, which is O (n)). The basic idea is that if and only if all numbers are present up to a certain index, then the list [index] = index + 1 (for example, list [0] = 1, list [1] = 2, etc. ) This property can be used to determine if the smallest missing number is before or after a specific list item, which allows you to perform a binary search.
The implementation is simple (I don't know php, so here's the pseudocode)
lower_bound = 0
upper_bound = length(list) - 1
index = floor((lower_bound + upper_bound) / 2)
while (lower_bound != upper_bound)
if(list[index] = index + 1) // missing number is after index
lower_bound = index + 1
index = floor((lower_bound + upper_bound) / 2)
else // missing number is at or before index
upper_bound = index
index = floor((lower_bound + upper_bound) / 2)
missing_number = upper_bound + 1 // add 1 because upper_bound is the index
And missing_numberwill be the smallest missing number, or if there will be missing numbers length(list) + 1.
Or using the recursion I hear is less efficient
first_missing_number(list, lower_bound, upper_bound) {
if(lower_bound = upper_bound)
return upper_bound + 1
index = floor((lower_bound + upper_bound) / 2)
if (list[index] = index + 1)
first_missing_number(list, index + 1, upper_bound)
else
first_missing_number(list, lower_bound, index)
}
first_missing_number(list, 0, length(list) - 1) , . , length(list) + 1.
, !
upd: php
function first_free($list) {
$lwr = 0;
$upr = count($list);
while ($lwr < $upr) {
$m = ($lwr + $upr) >> 1;
if($list[$m] == $m + 1)
$lwr = $m + 1;
else
$upr = $m;
}
return $upr + 1;
}