Compare commits
5 Commits
c637c55e42
...
a688ae2cd8
Author | SHA1 | Date |
---|---|---|
|
a688ae2cd8 | |
|
23f5b6b769 | |
|
9512a94b6d | |
|
0a065d259b | |
|
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 contains_duplicate_ii;
|
||||||
pub mod excel_sheet_column_number;
|
pub mod excel_sheet_column_number;
|
||||||
pub mod excel_sheet_column_title;
|
pub mod excel_sheet_column_title;
|
||||||
|
pub mod first_missing_positive;
|
||||||
|
pub mod fizz_buzz;
|
||||||
pub mod implement_strstr;
|
pub mod implement_strstr;
|
||||||
pub mod integer_to_roman;
|
pub mod integer_to_roman;
|
||||||
pub mod isomorphic_strings;
|
pub mod isomorphic_strings;
|
||||||
|
pub mod keyboard_row;
|
||||||
pub mod length_of_last_word;
|
pub mod length_of_last_word;
|
||||||
pub mod longest_common_prefix;
|
pub mod longest_common_prefix;
|
||||||
pub mod missing_number;
|
pub mod missing_number;
|
||||||
|
@ -13,8 +16,10 @@ pub mod palindrome_number;
|
||||||
pub mod plus_one;
|
pub mod plus_one;
|
||||||
pub mod reverse_integer;
|
pub mod reverse_integer;
|
||||||
pub mod roman_to_integer;
|
pub mod roman_to_integer;
|
||||||
|
pub mod set_mismatch;
|
||||||
pub mod two_sum;
|
pub mod two_sum;
|
||||||
pub mod valid_anagram;
|
pub mod valid_anagram;
|
||||||
|
pub mod valid_number;
|
||||||
pub mod valid_palindrome;
|
pub mod valid_palindrome;
|
||||||
pub mod valid_parenthesis;
|
pub mod valid_parenthesis;
|
||||||
pub mod word_pattern;
|
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