42 lines
1.2 KiB
Rust
42 lines
1.2 KiB
Rust
pub fn first_missing_positive(numbers: Vec<i32>) -> i32 {
|
|
let numbers_length = numbers.len();
|
|
|
|
// Mark all numbers below 1 and above the maximum range as i32::MAX.
|
|
let mut numbers = numbers
|
|
.into_iter()
|
|
.map(|number| {
|
|
if number < 1 || number > numbers_length as i32 {
|
|
i32::MAX
|
|
} else {
|
|
number
|
|
}
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
for index in 0..numbers_length {
|
|
// For each index get its number and subtract 1.
|
|
let index = numbers[index].unsigned_abs() as usize - 1;
|
|
|
|
// If that index then isn't i32::MAX - 1 (ie. negative or above range).
|
|
if index as i32 != i32::MAX - 1 {
|
|
// Then mark the number for that index as negative.
|
|
numbers[index] = -numbers[index].abs();
|
|
}
|
|
}
|
|
|
|
// Then the first positive number we find, the index of that number will be
|
|
// the first missing positive. And if there are only negative numbers, then
|
|
// the next positive number is the total amount of numbers + 1.
|
|
numbers
|
|
.into_iter()
|
|
.enumerate()
|
|
.find_map(|(index, number)| {
|
|
if number.is_positive() {
|
|
Some(index + 1)
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.unwrap_or(numbers_length + 1) as i32
|
|
}
|