Compare commits
5 Commits
c637c55e42
...
a688ae2cd8
Author | SHA1 | Date |
---|---|---|
Bauke | a688ae2cd8 | |
Bauke | 23f5b6b769 | |
Bauke | 9512a94b6d | |
Bauke | 0a065d259b | |
Bauke | e5fb926c91 |
|
@ -0,0 +1,36 @@
|
|||
pub fn first_missing_positive(mut numbers: Vec<i32>) -> 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
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
pub fn fizz_buzz(number: i32) -> Vec<String> {
|
||||
let mut result = vec![];
|
||||
|
||||
for index in 1..=number {
|
||||
let string = match (index % 3 == 0, index % 5 == 0) {
|
||||
(true, true) => "FizzBuzz".to_string(),
|
||||
(true, false) => "Fizz".to_string(),
|
||||
(false, true) => "Buzz".to_string(),
|
||||
(false, false) => index.to_string(),
|
||||
};
|
||||
|
||||
result.push(string);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
pub fn find_words(words: Vec<String>) -> Vec<String> {
|
||||
// Uncomment FromIterator in Leetcode since they're using Rust Edition 2018.
|
||||
// Edition 2021 has this trait in its prelude.
|
||||
|
||||
// use std::iter::FromIterator;
|
||||
use std::collections::HashSet;
|
||||
|
||||
fn hashset_from_str(string: &str) -> HashSet<char> {
|
||||
std::collections::HashSet::<_>::from_iter(string.to_lowercase().chars())
|
||||
}
|
||||
|
||||
let rows = [
|
||||
hashset_from_str("qwertyuiop"),
|
||||
hashset_from_str("asdfghjkl"),
|
||||
hashset_from_str("zxcvbnm"),
|
||||
];
|
||||
|
||||
let mut result = vec![];
|
||||
|
||||
for word in words {
|
||||
let word_set = hashset_from_str(&word);
|
||||
|
||||
if rows.iter().any(|row| word_set.is_subset(row)) {
|
||||
result.push(word);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
|
@ -3,9 +3,12 @@ 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;
|
||||
pub mod isomorphic_strings;
|
||||
pub mod keyboard_row;
|
||||
pub mod length_of_last_word;
|
||||
pub mod longest_common_prefix;
|
||||
pub mod missing_number;
|
||||
|
@ -13,8 +16,10 @@ pub mod palindrome_number;
|
|||
pub mod plus_one;
|
||||
pub mod reverse_integer;
|
||||
pub mod roman_to_integer;
|
||||
pub mod set_mismatch;
|
||||
pub mod two_sum;
|
||||
pub mod valid_anagram;
|
||||
pub mod valid_number;
|
||||
pub mod valid_palindrome;
|
||||
pub mod valid_parenthesis;
|
||||
pub mod word_pattern;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
pub fn find_error_nums(numbers: Vec<i32>) -> Vec<i32> {
|
||||
// Uncomment FromIterator in Leetcode since they're using Rust Edition 2018.
|
||||
// Edition 2021 has this trait in its prelude.
|
||||
|
||||
// use std::iter::FromIterator;
|
||||
use std::collections::HashSet;
|
||||
|
||||
let range = 1..=numbers.len() as i32;
|
||||
let mut numbers_set = HashSet::<_>::new();
|
||||
|
||||
let mut duplicate = 0;
|
||||
|
||||
for number in numbers {
|
||||
if numbers_set.insert(number) {
|
||||
continue;
|
||||
}
|
||||
|
||||
duplicate = number;
|
||||
}
|
||||
|
||||
let mut missing = 0;
|
||||
|
||||
for number in range {
|
||||
if !numbers_set.contains(&number) {
|
||||
missing = number;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vec![duplicate, missing]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
pub fn is_number(string: String) -> bool {
|
||||
let string = string.to_lowercase();
|
||||
|
||||
if string.contains("inf") || string.contains("nan") {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut parts = string.split("e");
|
||||
|
||||
let valid_significand = match parts.next() {
|
||||
Some(part) => part.parse::<f64>().is_ok(),
|
||||
None => unreachable!(),
|
||||
};
|
||||
|
||||
let valid_exponent = match parts.next() {
|
||||
Some(part) => part.parse::<isize>().is_ok(),
|
||||
None => true,
|
||||
};
|
||||
|
||||
let nothing_remaining = parts.next().is_none();
|
||||
|
||||
valid_significand && valid_exponent && nothing_remaining
|
||||
}
|
|
@ -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::<Vec<i32>>(), 500001; "massive")]
|
||||
fn test_first_missing_positive(input: &[i32], expected: i32) {
|
||||
assert_eq!(first_missing_positive(input.to_vec()), expected);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
use leetcode::fizz_buzz::fizz_buzz;
|
||||
|
||||
use test_case::test_case;
|
||||
|
||||
const EXAMPLE_3: &[&str] = &[
|
||||
"1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11",
|
||||
"Fizz", "13", "14", "FizzBuzz",
|
||||
];
|
||||
|
||||
#[test_case(3, &["1", "2", "Fizz"]; "example 1")]
|
||||
#[test_case(5, &["1", "2", "Fizz", "4", "Buzz"]; "example 2")]
|
||||
#[test_case(15, EXAMPLE_3; "example 3")]
|
||||
fn test_fizz_buzz(input: i32, expected: &[&str]) {
|
||||
assert_eq!(fizz_buzz(input), expected);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
use leetcode::keyboard_row::find_words;
|
||||
|
||||
use test_case::test_case;
|
||||
|
||||
#[test_case(&["Hello", "Alaska", "Dad", "Peace"], &["Alaska", "Dad"]; "example 1")]
|
||||
#[test_case(&["omk"], &[]; "example 2")]
|
||||
#[test_case(&["adsdf", "sfd"], &["adsdf", "sfd"]; "example 3")]
|
||||
fn test_keyboard_row(input: &[&str], expected: &[&str]) {
|
||||
assert_eq!(
|
||||
find_words(input.iter().map(ToString::to_string).collect()),
|
||||
expected
|
||||
);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
use leetcode::set_mismatch::find_error_nums;
|
||||
|
||||
use test_case::test_case;
|
||||
|
||||
#[test_case(&[1, 2, 2, 4], &[2, 3]; "example 1")]
|
||||
#[test_case(&[1, 1], &[1, 2]; "example 2")]
|
||||
#[test_case(&[2, 2], &[2, 1]; "edge 1")]
|
||||
#[test_case(&[3, 2, 3, 4, 6, 5], &[3, 1]; "edge 2")]
|
||||
#[test_case(&[3, 2, 2], &[2, 1]; "edge 3")]
|
||||
fn test_set_mismatch(input: &[i32], expected: &[i32]) {
|
||||
assert_eq!(find_error_nums(input.to_vec()), expected);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
use leetcode::valid_number::is_number;
|
||||
|
||||
use test_case::test_case;
|
||||
|
||||
#[test_case("0", true; "example 1")]
|
||||
#[test_case("e", false; "example 2")]
|
||||
#[test_case(".", false; "example 3")]
|
||||
#[test_case("-inf", false; "infinity")]
|
||||
#[test_case("NaN", false; "not a number")]
|
||||
#[test_case("", false; "empty")]
|
||||
fn test_valid_number(input: &str, expected: bool) {
|
||||
assert_eq!(is_number(input.to_string()), expected);
|
||||
}
|
Loading…
Reference in New Issue