From a688ae2cd89a121ce66906f705baa59142840c25 Mon Sep 17 00:00:00 2001 From: Bauke Date: Fri, 15 Apr 2022 23:50:20 +0200 Subject: [PATCH] Solve first-missing-positive. --- source/first_missing_positive/mod.rs | 36 ++++++++++++++++++++++++++++ source/lib.rs | 1 + tests/first_missing_positive.rs | 14 +++++++++++ 3 files changed, 51 insertions(+) create mode 100644 source/first_missing_positive/mod.rs create mode 100644 tests/first_missing_positive.rs diff --git a/source/first_missing_positive/mod.rs b/source/first_missing_positive/mod.rs new file mode 100644 index 0000000..c9df8d7 --- /dev/null +++ b/source/first_missing_positive/mod.rs @@ -0,0 +1,36 @@ +pub fn first_missing_positive(mut numbers: Vec) -> i32 { + let numbers_length = numbers.len(); + + // Mark all numbers below 1 and above the maximum range as i32::MAX. + for index in 0..numbers_length { + if numbers[index] < 1 || numbers[index] > numbers_length as i32 { + numbers[index] = i32::MAX; + } + } + + for index in 0..numbers_length { + // For each index get its number and subtract 1. + let index = numbers[index].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_else(|| numbers_length + 1) as i32 +} diff --git a/source/lib.rs b/source/lib.rs index 406452b..8da42e2 100644 --- a/source/lib.rs +++ b/source/lib.rs @@ -3,6 +3,7 @@ pub mod contains_duplicate; pub mod contains_duplicate_ii; pub mod excel_sheet_column_number; pub mod excel_sheet_column_title; +pub mod first_missing_positive; pub mod fizz_buzz; pub mod implement_strstr; pub mod integer_to_roman; diff --git a/tests/first_missing_positive.rs b/tests/first_missing_positive.rs new file mode 100644 index 0000000..7434404 --- /dev/null +++ b/tests/first_missing_positive.rs @@ -0,0 +1,14 @@ +use leetcode::first_missing_positive::first_missing_positive; + +use test_case::test_case; + +#[test_case(&[1, 2, 0], 3; "example 1")] +#[test_case(&[3, 4, -1, 1], 2; "example 2")] +#[test_case(&[7, 8, 9, 11, 12], 1; "example 3")] +#[test_case(&[1, 3, 2], 4; "maximum")] +#[test_case(&[1, 3, 3], 2; "duplicate")] +#[test_case(&[0], 1; "zero")] +#[test_case(&(0..=500000).into_iter().collect::>(), 500001; "massive")] +fn test_first_missing_positive(input: &[i32], expected: i32) { + assert_eq!(first_missing_positive(input.to_vec()), expected); +}