From c632067859cdaa95523c3dfc2e3b0ad5e32e6576 Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 9 Feb 2020 17:02:49 +0800 Subject: [PATCH 01/31] solve 318, 319, 326, 344, 345 --- src/solution/mod.rs | 5 ++ .../s0318_maximum_product_of_word_lengths.rs | 64 ++++++++++++++++++ src/solution/s0319_bulb_switcher.rs | 43 ++++++++++++ src/solution/s0326_power_of_three.rs | 58 ++++++++++++++++ src/solution/s0344_reverse_string.rs | 62 +++++++++++++++++ .../s0345_reverse_vowels_of_a_string.rs | 66 +++++++++++++++++++ 6 files changed, 298 insertions(+) create mode 100644 src/solution/s0318_maximum_product_of_word_lengths.rs create mode 100644 src/solution/s0319_bulb_switcher.rs create mode 100644 src/solution/s0326_power_of_three.rs create mode 100644 src/solution/s0344_reverse_string.rs create mode 100644 src/solution/s0345_reverse_vowels_of_a_string.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index 3b079b74..f47b270c 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -235,3 +235,8 @@ mod s0111_minimum_depth_of_binary_tree; mod s0092_reverse_linked_list_ii; mod s0303_range_sum_query_immutable; mod s0102_binary_tree_level_order_traversal; +mod s0318_maximum_product_of_word_lengths; +mod s0319_bulb_switcher; +mod s0326_power_of_three; +mod s0344_reverse_string; +mod s0345_reverse_vowels_of_a_string; diff --git a/src/solution/s0318_maximum_product_of_word_lengths.rs b/src/solution/s0318_maximum_product_of_word_lengths.rs new file mode 100644 index 00000000..c9ac8b46 --- /dev/null +++ b/src/solution/s0318_maximum_product_of_word_lengths.rs @@ -0,0 +1,64 @@ +/** + * [318] Maximum Product of Word Lengths + * + * Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0. + * + * Example 1: + * + * + * Input: ["abcw","baz","foo","bar","xtfn","abcdef"] + * Output: 16 + * Explanation: The two words can be "abcw", "xtfn". + * + * Example 2: + * + * + * Input: ["a","ab","abc","d","cd","bcd","abcd"] + * Output: 4 + * Explanation: The two words can be "ab", "cd". + * + * Example 3: + * + * + * Input: ["a","aa","aaa","aaaa"] + * Output: 0 + * Explanation: No such pair of words. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn max_product(words: Vec) -> i32 { + let mut ret = 0; + // use a int value to store word characters + // if a word contains 'a', then the resulting int is b'00000000000000000000000000000001' + // if it also contains 'b', then the resulting int is b'00000000000000000000000000000011' and so on + let mut values = vec![0; words.len()]; + for (i, word) in words.iter().enumerate() { + for c in word.as_bytes() { + values[i] |= 1 << (c - b'a'); + } + } + for i in 0..words.len() { + for j in i + 1..words.len() { + if values[i] & values[j] == 0 && words[i].len() * words[j].len() > ret { + ret = words[i].len() * words[j].len(); + } + } + } + ret as i32 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_318() {} +} diff --git a/src/solution/s0319_bulb_switcher.rs b/src/solution/s0319_bulb_switcher.rs new file mode 100644 index 00000000..a5ad315f --- /dev/null +++ b/src/solution/s0319_bulb_switcher.rs @@ -0,0 +1,43 @@ +/** + * [319] Bulb Switcher + * + * There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). For the i-th round, you toggle every i bulb. For the n-th round, you only toggle the last bulb. Find how many bulbs are on after n rounds. + * + * Example: + * + * + * Input: 3 + * Output: 1 + * Explanation: + * At first, the three bulbs are [off, off, off]. + * After first round, the three bulbs are [on, on, on]. + * After second round, the three bulbs are [on, off, on]. + * After third round, the three bulbs are [on, off, off]. + * + * So you should return 1, because there is only one bulb is on. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn bulb_switch(n: i32) -> i32 { + // number i bulb is toggled when round divides i, e.g. + // bulb 12 is toggled in round 1, 2, 3, 4, 6, 12 + // bulb 12's divisor comes in pairs, for example (2, 6), (3, 4) + // except for squres, e.g. 9 => 1, 3, 9, so it will be on + (n as f64).sqrt() as i32 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_319() {} +} diff --git a/src/solution/s0326_power_of_three.rs b/src/solution/s0326_power_of_three.rs new file mode 100644 index 00000000..6fa7467d --- /dev/null +++ b/src/solution/s0326_power_of_three.rs @@ -0,0 +1,58 @@ +/** + * [326] Power of Three + * + * Given an integer, write a function to determine if it is a power of three. + * + * Example 1: + * + * + * Input: 27 + * Output: true + * + * + * Example 2: + * + * + * Input: 0 + * Output: false + * + * Example 3: + * + * + * Input: 9 + * Output: true + * + * Example 4: + * + * + * Input: 45 + * Output: false + * + * Follow up:
+ * Could you do it without using any loop / recursion? + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn is_power_of_three(n: i32) -> bool { + if n == 0 { + return false; + } + if n == 1 { + return true; + } + n % 3 == 0 && Self::is_power_of_three(n / 3) + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_326() {} +} diff --git a/src/solution/s0344_reverse_string.rs b/src/solution/s0344_reverse_string.rs new file mode 100644 index 00000000..a3cd9d8e --- /dev/null +++ b/src/solution/s0344_reverse_string.rs @@ -0,0 +1,62 @@ +/** + * [344] Reverse String + * + * Write a function that reverses a string. The input string is given as an array of characters char[]. + * + * Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. + * + * You may assume all the characters consist of printable ascii characters. + * + * + * + *
+ * Example 1: + * + * + * Input: ["h","e","l","l","o"] + * Output: ["o","l","l","e","h"] + * + * + *
+ * Example 2: + * + * + * Input: ["H","a","n","n","a","h"] + * Output: ["h","a","n","n","a","H"] + * + *
+ *
+ */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn reverse_string(s: &mut Vec) { + if s.is_empty() { + return; + } + let (mut left, mut right) = (0, s.len() - 1); + while left < right { + let tmp = s[left]; + s[left] = s[right]; + s[right] = tmp; + left += 1; + right -= 1; + } + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_344() { + let mut s = vec![]; + Solution::reverse_string(&mut s); + println!("{:?}", s); + } +} diff --git a/src/solution/s0345_reverse_vowels_of_a_string.rs b/src/solution/s0345_reverse_vowels_of_a_string.rs new file mode 100644 index 00000000..28b4690a --- /dev/null +++ b/src/solution/s0345_reverse_vowels_of_a_string.rs @@ -0,0 +1,66 @@ +/** + * [345] Reverse Vowels of a String + * + * Write a function that takes a string as input and reverse only the vowels of a string. + * + * Example 1: + * + * + * Input: "hello" + * Output: "holle" + * + * + *
+ * Example 2: + * + * + * Input: "leetcode" + * Output: "leotcede" + *
+ * + * Note:
+ * The vowels does not include the letter "y". + * + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn reverse_vowels(s: String) -> String { + if s.is_empty() { + return s; + } + let vowels: Vec = "aeiouAEIOU".chars().collect(); + let mut chars: Vec = s.chars().collect(); + let (mut left, mut right) = (0, chars.len() - 1); + while left < right { + while !vowels.contains(&chars[left]) && left < right { + left += 1; + } + while !vowels.contains(&chars[right]) && left < right { + right -= 1; + } + if left < right { + let tmp = chars[left]; + chars[left] = chars[right]; + chars[right] = tmp; + left += 1; + right -= 1; + } + } + chars.into_iter().collect() + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_345() {} +} From cfd38d9175a52022523e91dbbe10c60d5345704e Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 9 Feb 2020 19:55:48 +0800 Subject: [PATCH 02/31] solve 349, 350, 367, 371 --- src/solution/mod.rs | 4 ++ .../s0349_intersection_of_two_arrays.rs | 60 +++++++++++++++++ .../s0350_intersection_of_two_arrays_ii.rs | 67 +++++++++++++++++++ src/solution/s0367_valid_perfect_square.rs | 61 +++++++++++++++++ src/solution/s0371_sum_of_two_integers.rs | 57 ++++++++++++++++ 5 files changed, 249 insertions(+) create mode 100644 src/solution/s0349_intersection_of_two_arrays.rs create mode 100644 src/solution/s0350_intersection_of_two_arrays_ii.rs create mode 100644 src/solution/s0367_valid_perfect_square.rs create mode 100644 src/solution/s0371_sum_of_two_integers.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index f47b270c..13d6eaf9 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -240,3 +240,7 @@ mod s0319_bulb_switcher; mod s0326_power_of_three; mod s0344_reverse_string; mod s0345_reverse_vowels_of_a_string; +mod s0349_intersection_of_two_arrays; +mod s0350_intersection_of_two_arrays_ii; +mod s0367_valid_perfect_square; +mod s0371_sum_of_two_integers; diff --git a/src/solution/s0349_intersection_of_two_arrays.rs b/src/solution/s0349_intersection_of_two_arrays.rs new file mode 100644 index 00000000..7f8063f5 --- /dev/null +++ b/src/solution/s0349_intersection_of_two_arrays.rs @@ -0,0 +1,60 @@ +use std::hash::Hash; + +/** + * [349] Intersection of Two Arrays + * + * Given two arrays, write a function to compute their intersection. + * + * Example 1: + * + * + * Input: nums1 = [1,2,2,1], nums2 = [2,2] + * Output: [2] + * + * + *
+ * Example 2: + * + * + * Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] + * Output: [9,4] + *
+ * + * Note: + * + * + * Each element in the result must be unique. + * The result can be in any order. + * + * + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn intersection(nums1: Vec, nums2: Vec) -> Vec { + use std::collections::HashSet; + let s1: HashSet = nums1.into_iter().collect(); + let s2: HashSet = nums2.into_iter().collect(); + let mut ret: HashSet = HashSet::new(); + for num1 in s1 { + if s2.contains(&num1) { + ret.insert(num1); + } + } + ret.into_iter().collect() + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_349() {} +} diff --git a/src/solution/s0350_intersection_of_two_arrays_ii.rs b/src/solution/s0350_intersection_of_two_arrays_ii.rs new file mode 100644 index 00000000..101916a3 --- /dev/null +++ b/src/solution/s0350_intersection_of_two_arrays_ii.rs @@ -0,0 +1,67 @@ +/** + * [350] Intersection of Two Arrays II + * + * Given two arrays, write a function to compute their intersection. + * + * Example 1: + * + * + * Input: nums1 = [1,2,2,1], nums2 = [2,2] + * Output: [2,2] + * + * + *
+ * Example 2: + * + * + * Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] + * Output: [4,9] + *
+ * + * Note: + * + * + * Each element in the result should appear as many times as it shows in both arrays. + * The result can be in any order. + * + * + * Follow up: + * + * + * What if the given array is already sorted? How would you optimize your algorithm? + * What if nums1's size is small compared to nums2's size? Which algorithm is better? + * What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once? + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn intersect(nums1: Vec, nums2: Vec) -> Vec { + let mut ret = vec![]; + let mut nums1 = nums1; + nums1.sort(); + let mut nums2 = nums2; + nums2.sort(); + + for num1 in nums1 { + if let Ok(index) = nums2.binary_search(&num1) { + ret.push(num1); + nums2.remove(index); + } + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_350() {} +} diff --git a/src/solution/s0367_valid_perfect_square.rs b/src/solution/s0367_valid_perfect_square.rs new file mode 100644 index 00000000..e9f99ab7 --- /dev/null +++ b/src/solution/s0367_valid_perfect_square.rs @@ -0,0 +1,61 @@ +/** + * [367] Valid Perfect Square + * + * Given a positive integer num, write a function which returns True if num is a perfect square else False. + * + * Note: Do not use any built-in library function such as sqrt. + * + * Example 1: + * + *
+ * + * Input: 16 + * Output: true + * + * + *
+ * Example 2: + * + * + * Input: 14 + * Output: false + * + *
+ *
+ */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn is_perfect_square(num: i32) -> bool { + if num == 0 || num == 1 { + return true; + } + // binary search + let (mut left, mut right) = (0, 100_000); + while left <= right { + let mid = left + (right - left) / 2; + if mid == num / mid { + return mid * mid == num; + } else if mid > num / mid { + right = mid - 1; + } else { + left = mid + 1; + } + } + false + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_367() { + println!("{}", Solution::is_perfect_square(1)); + } +} diff --git a/src/solution/s0371_sum_of_two_integers.rs b/src/solution/s0371_sum_of_two_integers.rs new file mode 100644 index 00000000..ef8f48b9 --- /dev/null +++ b/src/solution/s0371_sum_of_two_integers.rs @@ -0,0 +1,57 @@ +/** + * [371] Sum of Two Integers + * + * Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. + * + *
+ * Example 1: + * + * + * Input: a = 1, b = 2 + * Output: 3 + * + * + *
+ * Example 2: + * + * + * Input: a = -2, b = 3 + * Output: 1 + * + *
+ *
+ * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn get_sum(a: i32, b: i32) -> i32 { + // use `sum` to store direct sum without carriers + // use `carrier` to store carriers + let mut sum = a; + let mut carrier = b; + while sum != 0 && carrier != 0 { + let tmp_sum = sum; + sum = sum ^ carrier; + carrier = tmp_sum & carrier; + carrier <<= 1; + } + if sum == 0 { + carrier + } else { + sum + } + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_371() {} +} From 01222fe4060a6199ab2e5dc8f5dab318c1914dce Mon Sep 17 00:00:00 2001 From: songyzh Date: Mon, 10 Feb 2020 11:52:16 +0800 Subject: [PATCH 03/31] solve 383, 387 --- src/solution/mod.rs | 2 + src/solution/s0383_ransom_note.rs | 58 +++++++++++++++++++ ...0387_first_unique_character_in_a_string.rs | 48 +++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/solution/s0383_ransom_note.rs create mode 100644 src/solution/s0387_first_unique_character_in_a_string.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index 3b079b74..df98dd66 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -235,3 +235,5 @@ mod s0111_minimum_depth_of_binary_tree; mod s0092_reverse_linked_list_ii; mod s0303_range_sum_query_immutable; mod s0102_binary_tree_level_order_traversal; +mod s0383_ransom_note; +mod s0387_first_unique_character_in_a_string; diff --git a/src/solution/s0383_ransom_note.rs b/src/solution/s0383_ransom_note.rs new file mode 100644 index 00000000..07632028 --- /dev/null +++ b/src/solution/s0383_ransom_note.rs @@ -0,0 +1,58 @@ +use std::collections::HashMap; + +/** + * [383] Ransom Note + * + * + * Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom + * note can be constructed from the magazines ; otherwise, it will return false. + * + * + * Each letter in the magazine string can only be used once in your ransom note. + * + * + * Note:
+ * You may assume that both strings contain only lowercase letters. + * + * + * + * canConstruct("a", "b") -> false + * canConstruct("aa", "ab") -> false + * canConstruct("aa", "aab") -> true + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn can_construct(ransom_note: String, magazine: String) -> bool { + use std::collections::HashMap; + let mut map = HashMap::new(); + for c in magazine.chars() { + if map.contains_key(&c) { + map.insert(c, map.get(&c).unwrap() + 1); + } else { + map.insert(c, 1); + } + } + for c in ransom_note.chars() { + if !map.contains_key(&c) || map.get(&c).unwrap() < &1 { + return false; + } + map.insert(c, map.get(&c).unwrap() - 1); + } + true + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_383() {} +} diff --git a/src/solution/s0387_first_unique_character_in_a_string.rs b/src/solution/s0387_first_unique_character_in_a_string.rs new file mode 100644 index 00000000..e229c412 --- /dev/null +++ b/src/solution/s0387_first_unique_character_in_a_string.rs @@ -0,0 +1,48 @@ +/** + * [387] First Unique Character in a String + * + * + * Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. + * + * Examples: + * + * s = "leetcode" + * return 0. + * + * s = "loveleetcode", + * return 2. + * + * + * + * + * Note: You may assume the string contain only lowercase letters. + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn first_uniq_char(s: String) -> i32 { + let mut lookup = [0; 256]; + for c in s.chars() { + lookup[c as usize] = lookup[c as usize] + 1; + } + for (i, c) in s.chars().enumerate() { + if lookup[c as usize] == 1 { + return i as i32; + } + } + -1 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_387() {} +} From 094ba2aba8f03e04defe4ebe8c4595b486e39340 Mon Sep 17 00:00:00 2001 From: songyzh Date: Mon, 10 Feb 2020 17:26:38 +0800 Subject: [PATCH 04/31] solve 343, 409, 412, 414, 415, 434, 475 --- src/solution/mod.rs | 7 ++ src/solution/s0343_integer_break.rs | 72 ++++++++++++++++ src/solution/s0409_longest_palindrome.rs | 57 +++++++++++++ src/solution/s0412_fizz_buzz.rs | 63 ++++++++++++++ src/solution/s0414_third_maximum_number.rs | 81 ++++++++++++++++++ src/solution/s0415_add_strings.rs | 71 ++++++++++++++++ .../s0434_number_of_segments_in_a_string.rs | 42 ++++++++++ src/solution/s0475_heaters.rs | 82 +++++++++++++++++++ 8 files changed, 475 insertions(+) create mode 100644 src/solution/s0343_integer_break.rs create mode 100644 src/solution/s0409_longest_palindrome.rs create mode 100644 src/solution/s0412_fizz_buzz.rs create mode 100644 src/solution/s0414_third_maximum_number.rs create mode 100644 src/solution/s0415_add_strings.rs create mode 100644 src/solution/s0434_number_of_segments_in_a_string.rs create mode 100644 src/solution/s0475_heaters.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index df98dd66..713b0962 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -237,3 +237,10 @@ mod s0303_range_sum_query_immutable; mod s0102_binary_tree_level_order_traversal; mod s0383_ransom_note; mod s0387_first_unique_character_in_a_string; +mod s0409_longest_palindrome; +mod s0414_third_maximum_number; +mod s0475_heaters; +mod s0343_integer_break; +mod s0434_number_of_segments_in_a_string; +mod s0412_fizz_buzz; +mod s0415_add_strings; diff --git a/src/solution/s0343_integer_break.rs b/src/solution/s0343_integer_break.rs new file mode 100644 index 00000000..6b59b3ee --- /dev/null +++ b/src/solution/s0343_integer_break.rs @@ -0,0 +1,72 @@ +/** + * [343] Integer Break + * + * Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get. + * + * Example 1: + * + *
+ * + * Input: 2 + * Output: 1 + * Explanation: 2 = 1 + 1, 1 × 1 = 1. + * + *
+ * Example 2: + * + * + * Input: 10 + * Output: 36 + * Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36. + * + * Note: You may assume that n is not less than 2 and not larger than 58. + *
+ *
+ */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn integer_break(n: i32) -> i32 { + // dp + if n == 2 { + return 1; + } + if n == 3 { + return 2; + } + let mut dp = vec![0; (n + 1) as usize]; + // when used as factor, no need to break to addends + dp[2] = 2; + dp[3] = 3; + for i in 4..(n + 1) { + Self::helper(&mut dp, i); + } + dp[n as usize] + } + + fn helper(dp: &mut Vec, n: i32) { + let mut num1: usize = 2; + let mut num2: usize = n as usize - 2; + let mut res = 0; + while num1 <= num2 { + res = res.max(dp[num1] * dp[num2]); + num1 += 1; + num2 -= 1; + } + dp[n as usize] = res; + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_343() { + println!("{}", Solution::integer_break(10)); + } +} diff --git a/src/solution/s0409_longest_palindrome.rs b/src/solution/s0409_longest_palindrome.rs new file mode 100644 index 00000000..dc278265 --- /dev/null +++ b/src/solution/s0409_longest_palindrome.rs @@ -0,0 +1,57 @@ +/** + * [409] Longest Palindrome + * + * Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters. + * + * This is case sensitive, for example "Aa" is not considered a palindrome here. + * + * Note:
+ * Assume the length of given string will not exceed 1,010. + * + * + * Example: + * + * Input: + * "abccccdd" + * + * Output: + * 7 + * + * Explanation: + * One longest palindrome that can be built is "dccaccd", whose length is 7. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn longest_palindrome(s: String) -> i32 { + let mut lookup = vec![0; 256]; + for c in s.chars() { + lookup[c as usize] = lookup[c as usize] + 1; + } + let mut ret = 0; + let mut extra = 0; + for i in lookup { + if i % 2 == 1 { + extra = 1; + } + ret += i / 2 * 2; + } + ret + extra + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_409() { + println!("{}", Solution::longest_palindrome("abccccdd".to_string())); + } +} diff --git a/src/solution/s0412_fizz_buzz.rs b/src/solution/s0412_fizz_buzz.rs new file mode 100644 index 00000000..e68fa06f --- /dev/null +++ b/src/solution/s0412_fizz_buzz.rs @@ -0,0 +1,63 @@ +/** + * [412] Fizz Buzz + * + * Write a program that outputs the string representation of numbers from 1 to n. + * + * But for multiples of three it should output “Fizz” instead of the number and for the multiples of five output “Buzz”. For numbers which are multiples of both three and five output “FizzBuzz”. + * + * Example: + * + * n = 15, + * + * Return: + * [ + * "1", + * "2", + * "Fizz", + * "4", + * "Buzz", + * "Fizz", + * "7", + * "8", + * "Fizz", + * "Buzz", + * "11", + * "Fizz", + * "13", + * "14", + * "FizzBuzz" + * ] + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn fizz_buzz(n: i32) -> Vec { + let mut ret = vec![]; + for i in 1..(n + 1) { + if i % 15 == 0 { + ret.push("FizzBuzz".to_string()); + } else if i % 3 == 0 { + ret.push("Fizz".to_string()); + } else if i % 5 == 0 { + ret.push("Buzz".to_string()); + } else { + ret.push(i.to_string()); + } + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_412() {} +} diff --git a/src/solution/s0414_third_maximum_number.rs b/src/solution/s0414_third_maximum_number.rs new file mode 100644 index 00000000..4b4c7219 --- /dev/null +++ b/src/solution/s0414_third_maximum_number.rs @@ -0,0 +1,81 @@ +/** + * [414] Third Maximum Number + * + * Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). + * + * Example 1:
+ * + * Input: [3, 2, 1] + * + * Output: 1 + * + * Explanation: The third maximum is 1. + * + * + * + * Example 2:
+ * + * Input: [1, 2] + * + * Output: 2 + * + * Explanation: The third maximum does not exist, so the maximum (2) is returned instead. + * + * + * + * Example 3:
+ * + * Input: [2, 2, 3, 1] + * + * Output: 1 + * + * Explanation: Note that the third maximum here means the third maximum distinct number. + * Both numbers with value 2 are both considered as second maximum. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn third_max(nums: Vec) -> i32 { + // use min heap + let mut heap = vec![std::i64::MIN; 3]; + for num in nums { + let num = num as i64; + if heap.contains(&num) { + continue; + } + if num > heap[0] { + heap[0] = num; + if heap[0] > heap[1] { + let tmp = heap[0]; + heap[0] = heap[1]; + heap[1] = tmp; + } + if heap[0] > heap[2] { + let tmp = heap[0]; + heap[0] = heap[2]; + heap[2] = tmp; + } + } + } + if heap.contains(&std::i64::MIN) { + return heap[1].max(heap[2]) as i32; + } + heap[0] as i32 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_414() { + println!("{}", Solution::third_max(vec![1, 2, 2, 4])) + } +} diff --git a/src/solution/s0415_add_strings.rs b/src/solution/s0415_add_strings.rs new file mode 100644 index 00000000..d3ad1386 --- /dev/null +++ b/src/solution/s0415_add_strings.rs @@ -0,0 +1,71 @@ +/** + * [415] Add Strings + * + * Given two non-negative integers num1 and num2 represented as string, return the sum of num1 and num2. + * + * Note: + *
    + * The length of both num1 and num2 is < 5100. + * Both num1 and num2 contains only digits 0-9. + * Both num1 and num2 does not contain any leading zero. + * You must not use any built-in BigInteger library or convert the inputs to integer directly. + *
+ * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn add_strings(num1: String, num2: String) -> String { + let num1: Vec = num1.chars().collect(); + let num2: Vec = num2.chars().collect(); + let mut ret = String::new(); + let mut carrier = 0; + let mut index1 = (num1.len() - 1) as i32; + let mut index2 = (num2.len() - 1) as i32; + while index1 >= 0 && index2 >= 0 { + let sum = num1[index1 as usize].to_digit(10).unwrap() + + num2[index2 as usize].to_digit(10).unwrap() + + carrier; + let curr = sum % 10; + carrier = sum / 10; + ret = curr.to_string() + ret.as_str(); + index1 -= 1; + index2 -= 1; + } + while index1 >= 0 { + let sum = num1[index1 as usize].to_digit(10).unwrap() + carrier; + let curr = sum % 10; + carrier = sum / 10; + ret = curr.to_string() + ret.as_str(); + index1 -= 1; + } + while index2 >= 0 { + let sum = num2[index2 as usize].to_digit(10).unwrap() + carrier; + let curr = sum % 10; + carrier = sum / 10; + ret = curr.to_string() + ret.as_str(); + index2 -= 1; + } + if carrier == 1 { + ret = 1.to_string() + ret.as_str(); + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_415() { + println!( + "{}", + Solution::add_strings("1".to_string(), "9999".to_string()) + ); + } +} diff --git a/src/solution/s0434_number_of_segments_in_a_string.rs b/src/solution/s0434_number_of_segments_in_a_string.rs new file mode 100644 index 00000000..7c9bb060 --- /dev/null +++ b/src/solution/s0434_number_of_segments_in_a_string.rs @@ -0,0 +1,42 @@ +/** + * [434] Number of Segments in a String + * + * Count the number of segments in a string, where a segment is defined to be a contiguous sequence of non-space characters. + * + * Please note that the string does not contain any non-printable characters. + * + * Example: + * + * Input: "Hello, my name is John" + * Output: 5 + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn count_segments(s: String) -> i32 { + let mut ret = 0; + let mut prev_is_space = true; + for c in s.chars() { + let curr_is_space = c.is_whitespace(); + if prev_is_space && !curr_is_space { + ret += 1; + } + prev_is_space = curr_is_space; + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_434() {} +} diff --git a/src/solution/s0475_heaters.rs b/src/solution/s0475_heaters.rs new file mode 100644 index 00000000..e661f1aa --- /dev/null +++ b/src/solution/s0475_heaters.rs @@ -0,0 +1,82 @@ +/** + * [475] Heaters + * + * Winter is coming! Your first job during the contest is to design a standard heater with fixed warm radius to warm all the houses. + * + * Now, you are given positions of houses and heaters on a horizontal line, find out minimum radius of heaters so that all houses could be covered by those heaters. + * + * So, your input will be the positions of houses and heaters seperately, and your expected output will be the minimum radius standard of heaters. + * + * Note: + * + *
    + * Numbers of houses and heaters you are given are non-negative and will not exceed 25000. + * Positions of houses and heaters you are given are non-negative and will not exceed 10^9. + * As long as a house is in the heaters' warm radius range, it can be warmed. + * All the heaters follow your radius standard and the warm radius will the same. + *
+ * + * + * + * Example 1: + * + * + * Input: [1,2,3],[2] + * Output: 1 + * Explanation: The only heater was placed in the position 2, and if we use the radius 1 standard, then all the houses can be warmed. + * + * + * + * + * Example 2: + * + * + * Input: [1,2,3,4],[1,4] + * Output: 1 + * Explanation: The two heater was placed in the position 1 and 4. We need to use radius 1 standard, then all the houses can be warmed. + * + * + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn find_radius(houses: Vec, heaters: Vec) -> i32 { + use std::i32::MAX; + let mut houses = houses; + houses.sort(); + let mut heaters = heaters; + heaters.sort(); + let mut ret = 0; + for house in houses { + let index = heaters.binary_search(&house); + if let Err(index) = index { + let left = if index == 0 { + MAX + } else { + house - heaters[index - 1] + }; + let right = if index == heaters.len() { + MAX + } else { + heaters[index] - house + }; + ret = left.min(right).max(ret); + } + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_475() {} +} From c54f65c8e2713014eaedd6b3da0d63833effa308 Mon Sep 17 00:00:00 2001 From: songyzh Date: Tue, 11 Feb 2020 16:08:59 +0800 Subject: [PATCH 05/31] solve 437, 441, 443 --- src/solution/mod.rs | 3 + src/solution/s0437_path_sum_iii.rs | 99 ++++++++++++++++++++ src/solution/s0441_arranging_coins.rs | 73 +++++++++++++++ src/solution/s0443_string_compression.rs | 110 +++++++++++++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 src/solution/s0437_path_sum_iii.rs create mode 100644 src/solution/s0441_arranging_coins.rs create mode 100644 src/solution/s0443_string_compression.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index 273aeeb3..3a12d8fb 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -247,6 +247,9 @@ mod s0412_fizz_buzz; mod s0414_third_maximum_number; mod s0415_add_strings; mod s0434_number_of_segments_in_a_string; +mod s0437_path_sum_iii; +mod s0441_arranging_coins; +mod s0443_string_compression; mod s0475_heaters; mod s0509_fibonacci_number; mod s0704_binary_search; diff --git a/src/solution/s0437_path_sum_iii.rs b/src/solution/s0437_path_sum_iii.rs new file mode 100644 index 00000000..08057bd3 --- /dev/null +++ b/src/solution/s0437_path_sum_iii.rs @@ -0,0 +1,99 @@ +/** + * [437] Path Sum III + * + * You are given a binary tree in which each node contains an integer value. + * + * Find the number of paths that sum to a given value. + * + * The path does not need to start or end at the root or a leaf, but it must go downwards + * (traveling only from parent nodes to child nodes). + * + * The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. + * + * Example: + * + * root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 + * + * 10 + * / \ + * 5 -3 + * / \ \ + * 3 2 11 + * / \ \ + * 3 -2 1 + * + * Return 3. The paths that sum to 8 are: + * + * 1. 5 -> 3 + * 2. 5 -> 2 -> 1 + * 3. -3 -> 11 + * + * + */ +pub struct Solution {} +use crate::util::tree::{to_tree, TreeNode}; + +// submission codes start here + +// Definition for a binary tree node. +// #[derive(Debug, PartialEq, Eq)] +// pub struct TreeNode { +// pub val: i32, +// pub left: Option>>, +// pub right: Option>>, +// } +// +// impl TreeNode { +// #[inline] +// pub fn new(val: i32) -> Self { +// TreeNode { +// val, +// left: None, +// right: None +// } +// } +// } +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn path_sum(root: Option>>, sum: i32) -> i32 { + return Self::helper(&root, sum); + } + + pub fn helper(root: &Option>>, sum: i32) -> i32 { + if root.is_none() { + return 0; + } + let node = root.as_ref().unwrap(); + let val = node.borrow().val; + let left = &node.borrow().left; + let right = &node.borrow().right; + return Self::helper_include(root, sum) + + Self::helper(left, sum) + + Self::helper(right, sum); + } + + pub fn helper_include(root: &Option>>, sum: i32) -> i32 { + if root.is_none() { + return 0; + } + let node = root.as_ref().unwrap(); + let val = node.borrow().val; + let left = &node.borrow().left; + let right = &node.borrow().right; + let curr_res = if sum == val { 1 } else { 0 }; + return Self::helper_include(left, sum - val) + + Self::helper_include(right, sum - val) + + curr_res; + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_437() {} +} diff --git a/src/solution/s0441_arranging_coins.rs b/src/solution/s0441_arranging_coins.rs new file mode 100644 index 00000000..186daf15 --- /dev/null +++ b/src/solution/s0441_arranging_coins.rs @@ -0,0 +1,73 @@ +/** + * [441] Arranging Coins + * + * You have a total of n coins that you want to form in a staircase shape, where every k-th row must have exactly k coins. + * + * Given n, find the total number of full staircase rows that can be formed. + * + * n is a non-negative integer and fits within the range of a 32-bit signed integer. + * + * Example 1: + * + * n = 5 + * + * The coins can form the following rows: + * ¤ + * ¤ ¤ + * ¤ ¤ + * + * Because the 3rd row is incomplete, we return 2. + * + * + * + * Example 2: + * + * n = 8 + * + * The coins can form the following rows: + * ¤ + * ¤ ¤ + * ¤ ¤ ¤ + * ¤ ¤ + * + * Because the 4th row is incomplete, we return 3. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn arrange_coins(n: i32) -> i32 { + // x(x + 1) / 2 + reminder = n + // binary search + let mut left = 0; + let mut right = 100_000; + while left <= right { + let mid = left + (right - left) / 2; + let curr: i64 = mid * (mid + 1) / 2; + let reminder = n as i64 - curr; + if reminder >= mid + 1 { + left = mid + 1; + } else if reminder < 0 { + right = mid - 1; + } else { + return mid as i32; + } + } + 0 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_441() { + Solution::arrange_coins(5); + } +} diff --git a/src/solution/s0443_string_compression.rs b/src/solution/s0443_string_compression.rs new file mode 100644 index 00000000..1bb43d12 --- /dev/null +++ b/src/solution/s0443_string_compression.rs @@ -0,0 +1,110 @@ +/** + * [443] String Compression + * + * Given an array of characters, compress it in-place. + * + * The length after compression must always be smaller than or equal to the original array. + * + * Every element of the array should be a character (not int) of length 1. + * + * After you are done modifying the input array in-place, return the new length of the array. + * + * + * Follow up:
+ * Could you solve it using only O(1) extra space? + * + * + * Example 1: + * + * + * Input: + * ["a","a","b","b","c","c","c"] + * + * Output: + * Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"] + * + * Explanation: + * "aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3". + * + * + * + * + * Example 2: + * + * + * Input: + * ["a"] + * + * Output: + * Return 1, and the first 1 characters of the input array should be: ["a"] + * + * Explanation: + * Nothing is replaced. + * + * + * + * + * Example 3: + * + * + * Input: + * ["a","b","b","b","b","b","b","b","b","b","b","b","b"] + * + * Output: + * Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"]. + * + * Explanation: + * Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is replaced by "b12". + * Notice each digit has it's own entry in the array. + * + * + * + * + * Note: + * + *
    + * All characters have an ASCII value in [35, 126]. + * 1 <= len(chars) <= 1000. + *
+ * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn compress(chars: &mut Vec) -> i32 { + use std::char; + // add sentinel + chars.push('0'); + let mut left = 0; + let mut cnt: u32 = 1; + for i in 1..chars.len() { + let curr = chars[i]; + if chars[left] == curr { + cnt += 1; + } else { + if cnt > 1 { + for c in cnt.to_string().chars() { + left += 1; + chars[left] = c; + } + } + left += 1; + chars[left] = chars[i]; + cnt = 1; + } + } + return left as i32; + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_443() {} +} From b258896c36e8b8fc7b1c15f10fb14bb211ec3b6b Mon Sep 17 00:00:00 2001 From: songyzh Date: Tue, 11 Feb 2020 16:28:21 +0800 Subject: [PATCH 06/31] update readme --- README.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 587b18a2..491394e3 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,16 @@ -# My Leetcode Solution in Rust +# Leetcode Solution in Rust -Run `cargo run {id}` to initialize the template submission file of "question #id". +### TODO -Run `cargo test test_{id}` to test the solution for "question #id". +- [ ] update solutions +- [ ] add function to open discuss page +- [ ] generate default return type for complex problems to make code compile when problem initialized -对于大部分难度为 Hard 的问题, 会有中文的思路注释 +### Usage -Working in progress, to do: - -- [ ] auto generation of solution list (when 100 problems solved) - -## Usage - -* Remove all the solution .rs -* Clean lib.rs file -* Start your leetcode journey in rust by typing `cargo run {question_id}` +- cargo run + - {id}: initialize problem {id} in problem/ + - random: initialize random problem in problem/ + - solve {id}: move problem {id} from problem/ to solution/ + - all: initialize all problems From 4f20ca08a5ad6f2bfdccfd4145ef5cad98acf9a8 Mon Sep 17 00:00:00 2001 From: songyzh Date: Tue, 11 Feb 2020 18:49:22 +0800 Subject: [PATCH 07/31] solve 447, 448, 453, 455 --- src/problem/mod.rs | 4 ++ src/problem/p0447_number_of_boomerangs.rs | 62 ++++++++++++++++ ...ind_all_numbers_disappeared_in_an_array.rs | 58 +++++++++++++++ ...3_minimum_moves_to_equal_array_elements.rs | 44 ++++++++++++ src/problem/p0455_assign_cookies.rs | 71 +++++++++++++++++++ 5 files changed, 239 insertions(+) create mode 100644 src/problem/p0447_number_of_boomerangs.rs create mode 100644 src/problem/p0448_find_all_numbers_disappeared_in_an_array.rs create mode 100644 src/problem/p0453_minimum_moves_to_equal_array_elements.rs create mode 100644 src/problem/p0455_assign_cookies.rs diff --git a/src/problem/mod.rs b/src/problem/mod.rs index e69de29b..76e7727c 100644 --- a/src/problem/mod.rs +++ b/src/problem/mod.rs @@ -0,0 +1,4 @@ +mod p0447_number_of_boomerangs; +mod p0448_find_all_numbers_disappeared_in_an_array; +mod p0453_minimum_moves_to_equal_array_elements; +mod p0455_assign_cookies; diff --git a/src/problem/p0447_number_of_boomerangs.rs b/src/problem/p0447_number_of_boomerangs.rs new file mode 100644 index 00000000..01c710c0 --- /dev/null +++ b/src/problem/p0447_number_of_boomerangs.rs @@ -0,0 +1,62 @@ +/** + * [447] Number of Boomerangs + * + * Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters). + * + * Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive). + * + * Example: + * + * + * Input: + * [[0,0],[1,0],[2,0]] + * + * Output: + * 2 + * + * Explanation: + * The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]] + * + * + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn number_of_boomerangs(points: Vec>) -> i32 { + use std::collections::HashMap; + let mut ret = 0; + for (i, i_point) in points.iter().enumerate() { + let mut lookup = HashMap::new(); + for (j, j_point) in points.iter().enumerate() { + if i == j { + continue; + } + *lookup + .entry(Self::calc_distance(i_point, j_point)) + .or_insert(0) += 1; + } + for value in lookup.values() { + ret += value * (value - 1); + } + } + ret + } + + fn calc_distance(i_point: &Vec, j_point: &Vec) -> i32 { + (i_point[0] - j_point[0]).pow(2) + (i_point[1] - j_point[1]).pow(2) + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_447() {} +} diff --git a/src/problem/p0448_find_all_numbers_disappeared_in_an_array.rs b/src/problem/p0448_find_all_numbers_disappeared_in_an_array.rs new file mode 100644 index 00000000..c2409604 --- /dev/null +++ b/src/problem/p0448_find_all_numbers_disappeared_in_an_array.rs @@ -0,0 +1,58 @@ +/** + * [448] Find All Numbers Disappeared in an Array + * + * Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. + * + * Find all the elements of [1, n] inclusive that do not appear in this array. + * + * Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space. + * + * Example: + * + * Input: + * [4,3,2,7,8,2,3,1] + * + * Output: + * [5,6] + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn find_disappeared_numbers(nums: Vec) -> Vec { + // not best + let mut ret = vec![]; + let mut nums = nums; + nums.sort(); + let mut should_be = 1; + let mut index = 0; + while index < nums.len() { + if should_be == nums[index] { + should_be += 1; + index += 1; + } else if should_be > nums[index] { + index += 1; + } else { + ret.push(should_be); + should_be += 1; + } + } + for i in should_be..(nums.len() as i32 + 1) { + ret.push(i); + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_448() {} +} diff --git a/src/problem/p0453_minimum_moves_to_equal_array_elements.rs b/src/problem/p0453_minimum_moves_to_equal_array_elements.rs new file mode 100644 index 00000000..ba921c75 --- /dev/null +++ b/src/problem/p0453_minimum_moves_to_equal_array_elements.rs @@ -0,0 +1,44 @@ +/** + * [453] Minimum Moves to Equal Array Elements + * + * Given a non-empty integer array of size n, find the minimum number of moves required to make all array elements equal, where a move is incrementing n - 1 elements by 1. + * + * Example: + * + * Input: + * [1,2,3] + * + * Output: + * 3 + * + * Explanation: + * Only three moves are needed (remember each move increments two elements): + * + * [1,2,3] => [2,3,3] => [3,4,3] => [4,4,4] + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn min_moves(nums: Vec) -> i32 { + // all about math + // x * (n-1) + sum = n * (min + x) + // xn - x + sum = min*n + nx + // x = sum - min * n + let sum: i32 = nums.iter().sum(); + sum - *nums.iter().min().unwrap() * nums.len() as i32 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_453() {} +} diff --git a/src/problem/p0455_assign_cookies.rs b/src/problem/p0455_assign_cookies.rs new file mode 100644 index 00000000..f0d681ba --- /dev/null +++ b/src/problem/p0455_assign_cookies.rs @@ -0,0 +1,71 @@ +/** + * [455] Assign Cookies + * + * + * Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie. Each child i has a greed factor gi, which is the minimum size of a cookie that the child will be content with; and each cookie j has a size sj. If sj >= gi, we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number. + * + * + * Note:
+ * You may assume the greed factor is always positive.
+ * You cannot assign more than one cookie to one child. + * + * + * Example 1:
+ * + * Input: [1,2,3], [1,1] + * + * Output: 1 + * + * Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. + * And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content. + * You need to output 1. + * + * + * + * Example 2:
+ * + * Input: [1,2], [1,2,3] + * + * Output: 2 + * + * Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. + * You have 3 cookies and their sizes are big enough to gratify all of the children, + * You need to output 2. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn find_content_children(g: Vec, s: Vec) -> i32 { + let mut g = g; + g.sort(); + let mut s = s; + s.sort(); + let mut g_index = g.len() as i32 - 1; + let mut s_index = s.len() as i32 - 1; + let mut ret = 0; + while g_index >= 0 && s_index >= 0 { + if s[s_index as usize] >= g[g_index as usize] { + ret += 1; + s_index -= 1; + g_index -= 1; + } else { + g_index -= 1; + } + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_455() {} +} From a4ff8bb404274314a8cdd56b0980175b0d7b4ef6 Mon Sep 17 00:00:00 2001 From: songyzh Date: Tue, 11 Feb 2020 22:20:21 +0800 Subject: [PATCH 08/31] solve problems --- src/problem/mod.rs | 4 -- src/solution/mod.rs | 8 +++ .../s0447_number_of_boomerangs.rs} | 0 ...nd_all_numbers_disappeared_in_an_array.rs} | 0 ..._minimum_moves_to_equal_array_elements.rs} | 0 .../s0455_assign_cookies.rs} | 0 .../s0459_repeated_substring_pattern.rs | 68 +++++++++++++++++++ src/solution/s0461_hamming_distance.rs | 55 +++++++++++++++ src/solution/s0463_island_perimeter.rs | 66 ++++++++++++++++++ src/solution/s0476_number_complement.rs | 55 +++++++++++++++ 10 files changed, 252 insertions(+), 4 deletions(-) rename src/{problem/p0447_number_of_boomerangs.rs => solution/s0447_number_of_boomerangs.rs} (100%) rename src/{problem/p0448_find_all_numbers_disappeared_in_an_array.rs => solution/s0448_find_all_numbers_disappeared_in_an_array.rs} (100%) rename src/{problem/p0453_minimum_moves_to_equal_array_elements.rs => solution/s0453_minimum_moves_to_equal_array_elements.rs} (100%) rename src/{problem/p0455_assign_cookies.rs => solution/s0455_assign_cookies.rs} (100%) create mode 100644 src/solution/s0459_repeated_substring_pattern.rs create mode 100644 src/solution/s0461_hamming_distance.rs create mode 100644 src/solution/s0463_island_perimeter.rs create mode 100644 src/solution/s0476_number_complement.rs diff --git a/src/problem/mod.rs b/src/problem/mod.rs index 76e7727c..e69de29b 100644 --- a/src/problem/mod.rs +++ b/src/problem/mod.rs @@ -1,4 +0,0 @@ -mod p0447_number_of_boomerangs; -mod p0448_find_all_numbers_disappeared_in_an_array; -mod p0453_minimum_moves_to_equal_array_elements; -mod p0455_assign_cookies; diff --git a/src/solution/mod.rs b/src/solution/mod.rs index 3a12d8fb..e3bcec11 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -256,3 +256,11 @@ mod s0704_binary_search; mod s0969_pancake_sorting; mod s1018_binary_prefix_divisible_by_5; mod s1046_last_stone_weight; +mod s0459_repeated_substring_pattern; +mod s0461_hamming_distance; +mod s0447_number_of_boomerangs; +mod s0448_find_all_numbers_disappeared_in_an_array; +mod s0453_minimum_moves_to_equal_array_elements; +mod s0455_assign_cookies; +mod s0463_island_perimeter; +mod s0476_number_complement; diff --git a/src/problem/p0447_number_of_boomerangs.rs b/src/solution/s0447_number_of_boomerangs.rs similarity index 100% rename from src/problem/p0447_number_of_boomerangs.rs rename to src/solution/s0447_number_of_boomerangs.rs diff --git a/src/problem/p0448_find_all_numbers_disappeared_in_an_array.rs b/src/solution/s0448_find_all_numbers_disappeared_in_an_array.rs similarity index 100% rename from src/problem/p0448_find_all_numbers_disappeared_in_an_array.rs rename to src/solution/s0448_find_all_numbers_disappeared_in_an_array.rs diff --git a/src/problem/p0453_minimum_moves_to_equal_array_elements.rs b/src/solution/s0453_minimum_moves_to_equal_array_elements.rs similarity index 100% rename from src/problem/p0453_minimum_moves_to_equal_array_elements.rs rename to src/solution/s0453_minimum_moves_to_equal_array_elements.rs diff --git a/src/problem/p0455_assign_cookies.rs b/src/solution/s0455_assign_cookies.rs similarity index 100% rename from src/problem/p0455_assign_cookies.rs rename to src/solution/s0455_assign_cookies.rs diff --git a/src/solution/s0459_repeated_substring_pattern.rs b/src/solution/s0459_repeated_substring_pattern.rs new file mode 100644 index 00000000..f1ed8682 --- /dev/null +++ b/src/solution/s0459_repeated_substring_pattern.rs @@ -0,0 +1,68 @@ +/** + * [459] Repeated Substring Pattern + * + * Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000. + * + * + * + * Example 1: + * + * + * Input: "abab" + * Output: True + * Explanation: It's the substring "ab" twice. + * + * + * Example 2: + * + * + * Input: "aba" + * Output: False + * + * + * Example 3: + * + * + * Input: "abcabcabcabc" + * Output: True + * Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.) + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn repeated_substring_pattern(s: String) -> bool { + let chars: Vec = s.chars().collect(); + let mut pattern_len = s.len() / 2; + while pattern_len >= 1 { + if s.len() % pattern_len == 0 { + let substring = &s[0..pattern_len]; + let mut start = 0; + while start + pattern_len <= s.len() { + if &s[start..start + pattern_len] != substring { + break; + } + start += pattern_len; + } + if start == s.len() { + return true; + } + } + pattern_len -= 1; + } + false + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_459() {} +} diff --git a/src/solution/s0461_hamming_distance.rs b/src/solution/s0461_hamming_distance.rs new file mode 100644 index 00000000..2d6bc3e8 --- /dev/null +++ b/src/solution/s0461_hamming_distance.rs @@ -0,0 +1,55 @@ +/** + * [461] Hamming Distance + * + * The Hamming distance between two integers is the number of positions at which the corresponding bits are different. + * + * Given two integers x and y, calculate the Hamming distance. + * + * Note:
+ * 0 ≤ x, y < 2^31. + * + * + * Example: + * + * Input: x = 1, y = 4 + * + * Output: 2 + * + * Explanation: + * 1 (0 0 0 1) + * 4 (0 1 0 0) + * ↑ ↑ + * + * The above arrows point to positions where the corresponding bits are different. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn hamming_distance(x: i32, y: i32) -> i32 { + let mut ret = 0; + let mut x = x; + let mut y = y; + while x != 0 || y != 0 { + if x & 1 != y & 1 { + ret += 1; + } + x >>= 1; + y >>= 1; + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_461() {} +} diff --git a/src/solution/s0463_island_perimeter.rs b/src/solution/s0463_island_perimeter.rs new file mode 100644 index 00000000..eb63063e --- /dev/null +++ b/src/solution/s0463_island_perimeter.rs @@ -0,0 +1,66 @@ +/** + * [463] Island Perimeter + * + * You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. + * + * Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). + * + * The island doesn't have "lakes" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island. + * + * + * + * Example: + * + * + * Input: + * [[0,1,0,0], + * [1,1,1,0], + * [0,1,0,0], + * [1,1,0,0]] + * + * Output: 16 + * + * Explanation: The perimeter is the 16 yellow stripes in the image below: + * + * + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn island_perimeter(grid: Vec>) -> i32 { + let mut ret = 0; + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if grid[i][j] == 1 { + if i == 0 || grid[i - 1][j] == 0 { + ret += 1; + } + if i == grid.len() - 1 || grid[i + 1][j] == 0 { + ret += 1; + } + if j == 0 || grid[i][j - 1] == 0 { + ret += 1; + } + if j == grid[0].len() - 1 || grid[i][j + 1] == 0 { + ret += 1; + } + } + } + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_463() {} +} diff --git a/src/solution/s0476_number_complement.rs b/src/solution/s0476_number_complement.rs new file mode 100644 index 00000000..f7d21888 --- /dev/null +++ b/src/solution/s0476_number_complement.rs @@ -0,0 +1,55 @@ +/** + * [476] Number Complement + * + * Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation. + * + * Note:
+ *
    + * The given integer is guaranteed to fit within the range of a 32-bit signed integer. + * You could assume no leading zero bit in the integer’s binary representation. + *
+ * + * + * Example 1:
+ * + * Input: 5 + * Output: 2 + * Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2. + * + * + * + * Example 2:
+ * + * Input: 1 + * Output: 0 + * Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn find_complement(num: i32) -> i32 { + let mut num = num; + let mut ret = 0; + let mut offset = 0; + while num != 0 { + ret |= (1 - (num & 1)) << offset; + num >>= 1; + offset += 1; + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_476() {} +} From 5841187fed63dfde878af8f536cc70c20e3430d5 Mon Sep 17 00:00:00 2001 From: songyzh Date: Tue, 11 Feb 2020 22:22:19 +0800 Subject: [PATCH 09/31] update todo --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 491394e3..d84f7452 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ - [ ] update solutions - [ ] add function to open discuss page +- [ ] accept multiple ids +- [ ] accept range - [ ] generate default return type for complex problems to make code compile when problem initialized ### Usage From 44a466c44e1fb626361cf7b3619962bc3b904751 Mon Sep 17 00:00:00 2001 From: songyzh Date: Wed, 12 Feb 2020 10:46:51 +0800 Subject: [PATCH 10/31] update todo --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d84f7452..94df2e20 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ - [ ] accept multiple ids - [ ] accept range - [ ] generate default return type for complex problems to make code compile when problem initialized +- [ ] login +- [ ] verify on leetcode ### Usage From 898f897bc942c29c8fad2724ac8e70d022005c11 Mon Sep 17 00:00:00 2001 From: songyzh Date: Thu, 13 Feb 2020 17:15:54 +0800 Subject: [PATCH 11/31] solve 482, 485, 492, 496, 500 --- README.md | 1 + src/solution/mod.rs | 5 ++ src/solution/s0482_license_key_formatting.rs | 73 ++++++++++++++++++ src/solution/s0485_max_consecutive_ones.rs | 50 ++++++++++++ src/solution/s0492_construct_the_rectangle.rs | 52 +++++++++++++ src/solution/s0496_next_greater_element_i.rs | 77 +++++++++++++++++++ src/solution/s0500_keyboard_row.rs | 63 +++++++++++++++ 7 files changed, 321 insertions(+) create mode 100644 src/solution/s0482_license_key_formatting.rs create mode 100644 src/solution/s0485_max_consecutive_ones.rs create mode 100644 src/solution/s0492_construct_the_rectangle.rs create mode 100644 src/solution/s0496_next_greater_element_i.rs create mode 100644 src/solution/s0500_keyboard_row.rs diff --git a/README.md b/README.md index 94df2e20..e2589f60 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ ### TODO - [ ] update solutions +- [ ] add multiple solutions - [ ] add function to open discuss page - [ ] accept multiple ids - [ ] accept range diff --git a/src/solution/mod.rs b/src/solution/mod.rs index e3bcec11..4ae867bf 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -264,3 +264,8 @@ mod s0453_minimum_moves_to_equal_array_elements; mod s0455_assign_cookies; mod s0463_island_perimeter; mod s0476_number_complement; +mod s0482_license_key_formatting; +mod s0485_max_consecutive_ones; +mod s0492_construct_the_rectangle; +mod s0496_next_greater_element_i; +mod s0500_keyboard_row; diff --git a/src/solution/s0482_license_key_formatting.rs b/src/solution/s0482_license_key_formatting.rs new file mode 100644 index 00000000..0e6cce25 --- /dev/null +++ b/src/solution/s0482_license_key_formatting.rs @@ -0,0 +1,73 @@ +/** + * [482] License Key Formatting + * + * You are given a license key represented as a string S which consists only alphanumeric character and dashes. The string is separated into N+1 groups by N dashes. + * + * Given a number K, we would want to reformat the strings such that each group contains exactly K characters, except for the first group which could be shorter than K, but still must contain at least one character. Furthermore, there must be a dash inserted between two groups and all lowercase letters should be converted to uppercase. + * + * Given a non-empty string S and a number K, format the string according to the rules described above. + * + * Example 1:
+ * + * Input: S = "5F3Z-2e-9-w", K = 4 + * + * Output: "5F3Z-2E9W" + * + * Explanation: The string S has been split into two parts, each part has 4 characters. + * Note that the two extra dashes are not needed and can be removed. + * + * + * + * + * Example 2:
+ * + * Input: S = "2-5g-3-J", K = 2 + * + * Output: "2-5G-3J" + * + * Explanation: The string S has been split into three parts, each part has 2 characters except the first part as it could be shorter as mentioned above. + * + * + * + * Note:
+ *
    + * The length of string S will not exceed 12,000, and K is a positive integer. + * String S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9) and dashes(-). + * String S is non-empty. + *
+ * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn license_key_formatting(s: String, k: i32) -> String { + let mut ret = String::new(); + let mut curr_len = 0; + for c in s.chars().rev() { + if c == '-' { + continue; + } + if curr_len == k { + ret.insert(0, '-'); + ret.insert(0, c.to_ascii_uppercase()); + curr_len = 1; + } else { + ret.insert(0, c.to_ascii_uppercase()); + curr_len += 1; + } + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_482() {} +} diff --git a/src/solution/s0485_max_consecutive_ones.rs b/src/solution/s0485_max_consecutive_ones.rs new file mode 100644 index 00000000..9348962c --- /dev/null +++ b/src/solution/s0485_max_consecutive_ones.rs @@ -0,0 +1,50 @@ +/** + * [485] Max Consecutive Ones + * + * Given a binary array, find the maximum number of consecutive 1s in this array. + * + * Example 1:
+ * + * Input: [1,1,0,1,1,1] + * Output: 3 + * Explanation: The first two digits or the last three digits are consecutive 1s. + * The maximum number of consecutive 1s is 3. + * + * + * + * Note: + * + * The input array will only contain 0 and 1. + * The length of input array is a positive integer and will not exceed 10,000 + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn find_max_consecutive_ones(nums: Vec) -> i32 { + let mut ret = 0; + let mut curr = 0; + for num in nums { + if num == 1 { + curr += 1; + } else { + ret = ret.max(curr); + curr = 0; + } + } + ret.max(curr) + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_485() {} +} diff --git a/src/solution/s0492_construct_the_rectangle.rs b/src/solution/s0492_construct_the_rectangle.rs new file mode 100644 index 00000000..94074032 --- /dev/null +++ b/src/solution/s0492_construct_the_rectangle.rs @@ -0,0 +1,52 @@ +/** + * [492] Construct the Rectangle + * + * + * For a web developer, it is very important to know how to design a web page's size. So, given a specific rectangular web page’s area, your job by now is to design a rectangular web page, whose length L and width W satisfy the following requirements: + * 1. The area of the rectangular web page you designed must equal to the given target area. + *
2. The width W should not be larger than the length L, which means L >= W. + *
3. The difference between length L and width W should be as small as possible. + * + * You need to output the length L and the width W of the web page you designed in sequence. + * + * + * + * Example:
+ * + * Input: 4 + * Output: [2, 2] + * Explanation: The target area is 4, and all the possible ways to construct it are [1,4], [2,2], [4,1]. + * But according to requirement 2, [1,4] is illegal; according to requirement 3, [4,1] is not optimal compared to [2,2]. So the length L is 2, and the width W is 2. + * + * + * + * Note:
+ *
    + * The given area won't exceed 10,000,000 and is a positive integer + * The web page's width and length you designed must be positive integers. + *
+ * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn construct_rectangle(area: i32) -> Vec { + let mut w = (area as f64).sqrt() as i32; + while area % w != 0 { + w -= 1; + } + vec![area / w, w] + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_492() {} +} diff --git a/src/solution/s0496_next_greater_element_i.rs b/src/solution/s0496_next_greater_element_i.rs new file mode 100644 index 00000000..a58b04db --- /dev/null +++ b/src/solution/s0496_next_greater_element_i.rs @@ -0,0 +1,77 @@ +/** + * [496] Next Greater Element I + * + * + * You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2. + * + * + * + * The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number. + * + * + * Example 1:
+ * + * Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. + * Output: [-1,3,-1] + * Explanation: + * For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. + * For number 1 in the first array, the next greater number for it in the second array is 3. + * For number 2 in the first array, there is no next greater number for it in the second array, so output -1. + * + * + * + * Example 2:
+ * + * Input: nums1 = [2,4], nums2 = [1,2,3,4]. + * Output: [3,-1] + * Explanation: + * For number 2 in the first array, the next greater number for it in the second array is 3. + * For number 4 in the first array, there is no next greater number for it in the second array, so output -1. + * + * + * + * + * Note:
+ *
    + * All elements in nums1 and nums2 are unique. + * The length of both nums1 and nums2 would not exceed 1000. + *
+ * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { + use std::collections::HashMap; + let mut stack = vec![]; + let mut map = HashMap::new(); + // for every number in the pool, find the next greater number + for num2 in nums2 { + while stack.last().is_some() && *stack.last().unwrap() < num2 { + map.insert(stack.pop().unwrap(), num2); + } + stack.push(num2); + } + nums1 + .iter() + .map(|num1| *map.get(num1).unwrap_or(&-1)) + .collect() + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_496() { + println!( + "{:?}", + Solution::next_greater_element(vec![4, 1, 2], vec![1, 3, 4, 2]) + ) + } +} diff --git a/src/solution/s0500_keyboard_row.rs b/src/solution/s0500_keyboard_row.rs new file mode 100644 index 00000000..0a7d6aed --- /dev/null +++ b/src/solution/s0500_keyboard_row.rs @@ -0,0 +1,63 @@ +/** + * [500] Keyboard Row + * + * Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American keyboard like the image below. + * + * + * + * + * + * + * Example: + * + * + * Input: ["Hello", "Alaska", "Dad", "Peace"] + * Output: ["Alaska", "Dad"] + * + * + * + * + * Note: + * + *
    + * You may use one character in the keyboard more than once. + * You may assume the input string will only contain letters of alphabet. + *
+ * + */ +pub struct Solution {} + +// submission codes start here +use std::collections::HashMap; + +impl Solution { + pub fn find_words(words: Vec) -> Vec { + let mut map = HashMap::new(); + "qwertyuiop".chars().map(|c| map.insert(c, 1)).count(); + "asdfghjkl".chars().map(|c| map.insert(c, 2)).count(); + "zxcvbnm".chars().map(|c| map.insert(c, 3)).count(); + words + .into_iter() + .filter(|word| Self::helper(&map, &word.to_ascii_lowercase())) + .collect() + } + + fn helper(map: &HashMap, word: &String) -> bool { + for c in word.chars() { + if map.get(&c).unwrap() != map.get(&word.chars().nth(0usize).unwrap()).unwrap() { + return false; + } + } + true + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_500() {} +} From d159e0e0f59a583c362cb980f0d485ae24169026 Mon Sep 17 00:00:00 2001 From: songyzh Date: Thu, 13 Feb 2020 20:12:45 +0800 Subject: [PATCH 12/31] solve 322 --- src/solution/mod.rs | 1 + src/solution/s0322_coin_change.rs | 55 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/solution/s0322_coin_change.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index 4ae867bf..cba60b9b 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -269,3 +269,4 @@ mod s0485_max_consecutive_ones; mod s0492_construct_the_rectangle; mod s0496_next_greater_element_i; mod s0500_keyboard_row; +mod s0322_coin_change; diff --git a/src/solution/s0322_coin_change.rs b/src/solution/s0322_coin_change.rs new file mode 100644 index 00000000..08cad772 --- /dev/null +++ b/src/solution/s0322_coin_change.rs @@ -0,0 +1,55 @@ +/** + * [322] Coin Change + * + * You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1. + * + * Example 1: + * + * + * Input: coins = [1, 2, 5], amount = 11 + * Output: 3 + * Explanation: 11 = 5 + 5 + 1 + * + * Example 2: + * + * + * Input: coins = [2], amount = 3 + * Output: -1 + * + * + * Note:
+ * You may assume that you have an infinite number of each kind of coin. + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn coin_change(coins: Vec, amount: i32) -> i32 { + let mut dp = vec![amount + 1; amount as usize + 1]; + dp[0] = 0; + for a in 1..(amount + 1) { + for coin in &coins { + if a >= *coin { + dp[a as usize] = dp[a as usize].min(dp[(a - *coin) as usize] + 1); + } + } + } + if dp[amount as usize] > amount { + -1 + } else { + dp[amount as usize] + } + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_322() {} +} From 470e4a568075b96aa3686be0508afaa40a1c1fe8 Mon Sep 17 00:00:00 2001 From: songyzh Date: Fri, 14 Feb 2020 19:13:42 +0800 Subject: [PATCH 13/31] solve 328, 331 --- src/solution/mod.rs | 2 + src/solution/s0328_odd_even_linked_list.rs | 90 +++++++++++++++++++ ...preorder_serialization_of_a_binary_tree.rs | 75 ++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 src/solution/s0328_odd_even_linked_list.rs create mode 100644 src/solution/s0331_verify_preorder_serialization_of_a_binary_tree.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index cba60b9b..ec9c0a05 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -270,3 +270,5 @@ mod s0492_construct_the_rectangle; mod s0496_next_greater_element_i; mod s0500_keyboard_row; mod s0322_coin_change; +mod s0328_odd_even_linked_list; +mod s0331_verify_preorder_serialization_of_a_binary_tree; diff --git a/src/solution/s0328_odd_even_linked_list.rs b/src/solution/s0328_odd_even_linked_list.rs new file mode 100644 index 00000000..2bc0cc03 --- /dev/null +++ b/src/solution/s0328_odd_even_linked_list.rs @@ -0,0 +1,90 @@ +/** + * [328] Odd Even Linked List + * + * Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes. + * + * You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity. + * + * Example 1: + * + * + * Input: 1->2->3->4->5->NULL + * Output: 1->3->5->2->4->NULL + * + * + * Example 2: + * + * + * Input: 2->1->3->5->6->4->7->NULL + * Output: 2->3->6->7->1->5->4->NULL + * + * + * Note: + * + * + * The relative order inside both the even and odd groups should remain as it was in the input. + * The first node is considered odd, the second node even and so on ... + * + * + */ +pub struct Solution {} +use crate::util::linked_list::{to_list, ListNode}; + +// submission codes start here + +// Definition for singly-linked list. +// #[derive(PartialEq, Eq, Clone, Debug)] +// pub struct ListNode { +// pub val: i32, +// pub next: Option> +// } +// +// impl ListNode { +// #[inline] +// fn new(val: i32) -> Self { +// ListNode { +// next: None, +// val +// } +// } +// } +impl Solution { + pub fn odd_even_list(head: Option>) -> Option> { + if head.is_none() || head.as_ref().unwrap().next.is_none() { + return head; + } + let mut head = head; + let mut dummy1 = Some(Box::new(ListNode::new(0))); + let mut dummy1_ref = dummy1.as_mut(); + let mut dummy2 = Some(Box::new(ListNode::new(0))); + let mut dummy2_ref = dummy2.as_mut(); + let mut is_even = true; + while head.is_some() { + let next = head.as_mut().unwrap().next.take(); + if is_even { + dummy1_ref.as_mut().unwrap().next = head.take(); + dummy1_ref = dummy1_ref.unwrap().next.as_mut(); + } else { + dummy2_ref.as_mut().unwrap().next = head.take(); + dummy2_ref = dummy2_ref.unwrap().next.as_mut(); + } + head = next; + is_even = !is_even; + } + dummy2_ref.as_mut().unwrap().next = None; + dummy1_ref.as_mut().unwrap().next = dummy2.unwrap().next; + dummy1.unwrap().next + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_328() { + println!("{:?}", Solution::odd_even_list(linked![1, 2, 3, 4, 5])) + } +} diff --git a/src/solution/s0331_verify_preorder_serialization_of_a_binary_tree.rs b/src/solution/s0331_verify_preorder_serialization_of_a_binary_tree.rs new file mode 100644 index 00000000..93129554 --- /dev/null +++ b/src/solution/s0331_verify_preorder_serialization_of_a_binary_tree.rs @@ -0,0 +1,75 @@ +/** + * [331] Verify Preorder Serialization of a Binary Tree + * + * One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #. + * + * + * _9_ + * / \ + * 3 2 + * / \ / \ + * 4 1 # 6 + * / \ / \ / \ + * # # # # # # + * + * + * For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node. + * + * Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree. + * + * Each comma separated value in the string must be either an integer or a character '#' representing null pointer. + * + * You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3". + * + * Example 1: + * + * + * Input: "9,3,4,#,#,1,#,#,2,#,6,#,#" + * Output: true + * + * Example 2: + * + * + * Input: "1,#" + * Output: false + * + * + * Example 3: + * + * + * Input: "9,#,#,1" + * Output: false + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn is_valid_serialization(preorder: String) -> bool { + // use stack + let mut hashes = vec![]; + for c in preorder.split(',').rev() { + if c == "," { + continue; + } else if c == "#" { + hashes.push(c); + } else { + if hashes.len() < 2 { + return false; + } + hashes.pop(); + } + } + hashes.len() == 1 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_331() {} +} From 696f0a3f11b13218d65506015c415e7e05ce19a0 Mon Sep 17 00:00:00 2001 From: songyzh Date: Fri, 14 Feb 2020 20:10:19 +0800 Subject: [PATCH 14/31] solve 337 --- src/solution/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/solution/mod.rs b/src/solution/mod.rs index ec9c0a05..012ae105 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -272,3 +272,4 @@ mod s0500_keyboard_row; mod s0322_coin_change; mod s0328_odd_even_linked_list; mod s0331_verify_preorder_serialization_of_a_binary_tree; +mod s0337_house_robber_iii; From 6f94a607e86efa203e76413559841ed5fa03c10a Mon Sep 17 00:00:00 2001 From: songyzh Date: Sat, 15 Feb 2020 15:10:41 +0800 Subject: [PATCH 15/31] solve 337, 347, 357, 368, 373 --- src/solution/mod.rs | 4 + src/solution/s0337_house_robber_iii.rs | 107 ++++++++++++++++++ src/solution/s0347_top_k_frequent_elements.rs | 54 +++++++++ .../s0357_count_numbers_with_unique_digits.rs | 56 +++++++++ .../s0368_largest_divisible_subset.rs | 71 ++++++++++++ .../s0373_find_k_pairs_with_smallest_sums.rs | 88 ++++++++++++++ 6 files changed, 380 insertions(+) create mode 100644 src/solution/s0337_house_robber_iii.rs create mode 100644 src/solution/s0347_top_k_frequent_elements.rs create mode 100644 src/solution/s0357_count_numbers_with_unique_digits.rs create mode 100644 src/solution/s0368_largest_divisible_subset.rs create mode 100644 src/solution/s0373_find_k_pairs_with_smallest_sums.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index 012ae105..b29d172d 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -273,3 +273,7 @@ mod s0322_coin_change; mod s0328_odd_even_linked_list; mod s0331_verify_preorder_serialization_of_a_binary_tree; mod s0337_house_robber_iii; +mod s0347_top_k_frequent_elements; +mod s0357_count_numbers_with_unique_digits; +mod s0368_largest_divisible_subset; +mod s0373_find_k_pairs_with_smallest_sums; diff --git a/src/solution/s0337_house_robber_iii.rs b/src/solution/s0337_house_robber_iii.rs new file mode 100644 index 00000000..9f8b158d --- /dev/null +++ b/src/solution/s0337_house_robber_iii.rs @@ -0,0 +1,107 @@ +/** + * [337] House Robber III + * + * The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night. + * + * Determine the maximum amount of money the thief can rob tonight without alerting the police. + * + * Example 1: + * + * + * Input: [3,2,3,null,3,null,1] + * + * 3 + * / \ + * 2 3 + * \ \ + * 3 1 + * + * Output: 7 + * Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7. + * + * Example 2: + * + * + * Input: [3,4,5,1,3,null,1] + * + * 3 + * / \ + * 4 5 + * / \ \ + * 1 3 1 + * + * Output: 9 + * Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9. + * + */ +pub struct Solution {} +use crate::util::tree::{to_tree, TreeNode}; + +// submission codes start here + +// Definition for a binary tree node. +// #[derive(Debug, PartialEq, Eq)] +// pub struct TreeNode { +// pub val: i32, +// pub left: Option>>, +// pub right: Option>>, +// } +// +// impl TreeNode { +// #[inline] +// pub fn new(val: i32) -> Self { +// TreeNode { +// val, +// left: None, +// right: None +// } +// } +// } +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn rob(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + let left = root.as_ref().unwrap().borrow().left.clone(); + let right = root.as_ref().unwrap().borrow().right.clone(); + if left.is_none() && right.is_none() { + return root.unwrap().borrow().val; + } + let (left_left, left_right) = if left.is_none() { + (None, None) + } else { + ( + left.as_ref().unwrap().borrow().left.clone(), + left.as_ref().unwrap().borrow().right.clone(), + ) + }; + + let (right_left, right_right) = if right.is_none() { + (None, None) + } else { + ( + right.as_ref().unwrap().borrow().left.clone(), + right.as_ref().unwrap().borrow().right.clone(), + ) + }; + + (root.unwrap().borrow().val + + Self::rob(left_left) + + Self::rob(left_right) + + Self::rob(right_left) + + Self::rob(right_right)) + .max(Self::rob(left) + Self::rob(right)) + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_337() {} +} diff --git a/src/solution/s0347_top_k_frequent_elements.rs b/src/solution/s0347_top_k_frequent_elements.rs new file mode 100644 index 00000000..64a40e53 --- /dev/null +++ b/src/solution/s0347_top_k_frequent_elements.rs @@ -0,0 +1,54 @@ +/** + * [347] Top K Frequent Elements + * + * Given a non-empty array of integers, return the k most frequent elements. + * + * Example 1: + * + * + * Input: nums = [1,1,1,2,2,3], k = 2 + * Output: [1,2] + * + * + *
+ * Example 2: + * + * + * Input: nums = [1], k = 1 + * Output: [1] + *
+ * + * Note: + * + * + * You may assume k is always valid, 1 ≤ k ≤ number of unique elements. + * Your algorithm's time complexity must be better than O(n log n), where n is the array's size. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn top_k_frequent(nums: Vec, k: i32) -> Vec { + use std::collections::HashMap; + let mut map = HashMap::new(); + nums.iter() + .map(|num| *map.entry(*num).or_insert(0) += 1) + .count(); + let mut nums: Vec = map.keys().map(|num| *num).collect(); + nums.sort_by_key(|num| -*map.get(num).unwrap()); + nums[0..k as usize].to_vec() + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_347() {} +} diff --git a/src/solution/s0357_count_numbers_with_unique_digits.rs b/src/solution/s0357_count_numbers_with_unique_digits.rs new file mode 100644 index 00000000..cc4a5f61 --- /dev/null +++ b/src/solution/s0357_count_numbers_with_unique_digits.rs @@ -0,0 +1,56 @@ +/** + * [357] Count Numbers with Unique Digits + * + * Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10^n. + * + *
+ * Example: + * + * + * Input: 2 + * Output: 91 + * Explanation: The answer should be the total numbers in the range of 0 ≤ x < 100, + * excluding 11,22,33,44,55,66,77,88,99 + * + *
+ */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn count_numbers_with_unique_digits(n: i32) -> i32 { + if n == 0 { + return 0; + } + if n == 1 { + return 10; + } + if n == 2 { + return 91; + } + let mut dp = vec![0; n as usize + 1]; + dp[1] = 10; + dp[2] = 91; + for i in 3..(n + 1) { + let mut curr = 9; + let mut remain = 9; + for _ in 0..(i - 1) { + curr *= remain; + remain -= 1; + } + dp[i as usize] = dp[i as usize - 1] + curr; + } + dp[n as usize] + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_357() {} +} diff --git a/src/solution/s0368_largest_divisible_subset.rs b/src/solution/s0368_largest_divisible_subset.rs new file mode 100644 index 00000000..85ce6e8d --- /dev/null +++ b/src/solution/s0368_largest_divisible_subset.rs @@ -0,0 +1,71 @@ +/** + * [368] Largest Divisible Subset + * + * Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: + * + * Si % Sj = 0 or Sj % Si = 0. + * + * If there are multiple solutions, return any subset is fine. + * + * Example 1: + * + *
+ * + * Input: [1,2,3] + * Output: [1,2] (of course, [1,3] will also be ok) + * + * + *
+ * Example 2: + * + * + * Input: [1,2,4,8] + * Output: [1,2,4,8] + * + *
+ *
+ */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn largest_divisible_subset(nums: Vec) -> Vec { + let mut nums = nums; + nums.sort(); + let mut prev_indices: Vec = vec![-1; nums.len()]; + let mut dp = vec![1; nums.len()]; + let mut max_count = 0; + let mut max_index: i32 = -1; + for i in 0..nums.len() { + for j in (0..i).rev() { + if nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i] { + dp[i] = dp[j] + 1; + prev_indices[i] = j as i32; + } + } + if dp[i] > max_count { + max_count = dp[i]; + max_index = i as i32; + } + } + let mut ret = vec![]; + while max_index != -1 { + ret.push(nums[max_index as usize]); + max_index = prev_indices[max_index as usize]; + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_368() { + println!("{:?}", Solution::largest_divisible_subset(vec![1, 2, 3])); + } +} diff --git a/src/solution/s0373_find_k_pairs_with_smallest_sums.rs b/src/solution/s0373_find_k_pairs_with_smallest_sums.rs new file mode 100644 index 00000000..4c11927e --- /dev/null +++ b/src/solution/s0373_find_k_pairs_with_smallest_sums.rs @@ -0,0 +1,88 @@ +/** + * [373] Find K Pairs with Smallest Sums + * + * You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. + * + * Define a pair (u,v) which consists of one element from the first array and one element from the second array. + * + * Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums. + * + * Example 1: + * + * + * Input: nums1 = [1,7,11], nums2 = [2,4,6], k = 3 + * Output: [[1,2],[1,4],[1,6]] + * Explanation: The first 3 pairs are returned from the sequence: + * [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6] + * + * Example 2: + * + * + * Input: nums1 = [1,1,2], nums2 = [1,2,3], k = 2 + * Output: [1,1],[1,1] + * Explanation: The first 2 pairs are returned from the sequence: + * [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3] + * + * Example 3: + * + * + * Input: nums1 = [1,2], nums2 = [3], k = 3 + * Output: [1,3],[2,3] + * Explanation: All possible pairs are returned from the sequence: [1,3],[2,3] + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn k_smallest_pairs(nums1: Vec, nums2: Vec, k: i32) -> Vec> { + // use a max heap + use std::collections::BinaryHeap; + let k = k as usize; + let mut max_heap = BinaryHeap::with_capacity(k); + for num1 in &nums1 { + for num2 in &nums2 { + let sum = *num1 + *num2; + if max_heap.len() < k { + max_heap.push(sum); + } else { + let mut top = max_heap.peek_mut().unwrap(); + if sum < *top { + *top = sum; + } + } + } + } + let mut ret = vec![]; + let top = max_heap.peek(); + if top.is_none() { + return ret; + } + let top = *top.unwrap(); + for num1 in &nums1 { + for num2 in &nums2 { + let sum = *num1 + *num2; + if sum <= top { + ret.push(vec![*num1, *num2]); + } + } + } + ret.sort_by_key(|v| v[0] + v[1]); + if ret.len() > k { + ret.split_off(k); + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_373() {} +} From 593b7f75ce5f0dc90164ef82c6629a9a3a0f8d56 Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 16 Feb 2020 11:19:54 +0800 Subject: [PATCH 16/31] solve 375, 377, 378 --- src/solution/mod.rs | 3 + .../s0375_guess_number_higher_or_lower_ii.rs | 64 +++++++++++++++++ src/solution/s0377_combination_sum_iv.rs | 69 +++++++++++++++++++ ...kth_smallest_element_in_a_sorted_matrix.rs | 66 ++++++++++++++++++ 4 files changed, 202 insertions(+) create mode 100644 src/solution/s0375_guess_number_higher_or_lower_ii.rs create mode 100644 src/solution/s0377_combination_sum_iv.rs create mode 100644 src/solution/s0378_kth_smallest_element_in_a_sorted_matrix.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index b29d172d..6cc29d19 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -277,3 +277,6 @@ mod s0347_top_k_frequent_elements; mod s0357_count_numbers_with_unique_digits; mod s0368_largest_divisible_subset; mod s0373_find_k_pairs_with_smallest_sums; +mod s0375_guess_number_higher_or_lower_ii; +mod s0377_combination_sum_iv; +mod s0378_kth_smallest_element_in_a_sorted_matrix; diff --git a/src/solution/s0375_guess_number_higher_or_lower_ii.rs b/src/solution/s0375_guess_number_higher_or_lower_ii.rs new file mode 100644 index 00000000..9903e884 --- /dev/null +++ b/src/solution/s0375_guess_number_higher_or_lower_ii.rs @@ -0,0 +1,64 @@ +/** + * [375] Guess Number Higher or Lower II + * + * We are playing the Guess Game. The game is as follows: + * + * I pick a number from 1 to n. You have to guess which number I picked. + * + * Every time you guess wrong, I'll tell you whether the number I picked is higher or lower. + * + * However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked. + * + * Example: + * + * + * n = 10, I pick 8. + * + * First round: You guess 5, I tell you that it's higher. You pay $5. + * Second round: You guess 7, I tell you that it's higher. You pay $7. + * Third round: You guess 9, I tell you that it's lower. You pay $9. + * + * Game over. 8 is the number I picked. + * + * You end up paying $5 + $7 + $9 = $21. + * + * + * Given a particular n ≥ 1, find out how much money you need to have to guarantee a win. + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn get_money_amount(n: i32) -> i32 { + use std::i32::MAX; + let n = n as usize; + let mut dp = vec![vec![0; n + 1]; n + 1]; + for i in (1..n + 1).rev() { + for j in i + 1..n + 1 { + if i + 1 == j { + dp[i][j] = i; + continue; + } + let mut curr = MAX; + for k in i + 1..j { + curr = curr.min(k as i32 + dp[i][k - 1].max(dp[k + 1][j]) as i32); + } + dp[i][j] = curr as usize; + } + } + dp[1][n] as i32 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_375() { + println!("{}", Solution::get_money_amount(5)); + } +} diff --git a/src/solution/s0377_combination_sum_iv.rs b/src/solution/s0377_combination_sum_iv.rs new file mode 100644 index 00000000..1d693113 --- /dev/null +++ b/src/solution/s0377_combination_sum_iv.rs @@ -0,0 +1,69 @@ +/** + * [377] Combination Sum IV + * + * Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target. + * + * Example: + * + * + * nums = [1, 2, 3] + * target = 4 + * + * The possible combination ways are: + * (1, 1, 1, 1) + * (1, 1, 2) + * (1, 2, 1) + * (1, 3) + * (2, 1, 1) + * (2, 2) + * (3, 1) + * + * Note that different sequences are counted as different combinations. + * + * Therefore the output is 7. + * + * + * + * + * Follow up:
+ * What if negative numbers are allowed in the given array?
+ * How does it change the problem?
+ * What limitation we need to add to the question to allow negative numbers? + * + * Credits:
+ * Special thanks to @pbrother for adding this problem and creating all test cases. + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn combination_sum4(nums: Vec, target: i32) -> i32 { + let target = target as usize; + let mut dp = vec![0; target + 1]; + for t in 1..target + 1 { + for num in &nums { + let num = *num as usize; + if num == t { + dp[t] += 1; + } else if num < t { + dp[t] += dp[t - num]; + } + } + } + dp[target] + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_377() { + println!("{:?}", Solution::combination_sum4(vec![1, 2, 3], 4)); + } +} diff --git a/src/solution/s0378_kth_smallest_element_in_a_sorted_matrix.rs b/src/solution/s0378_kth_smallest_element_in_a_sorted_matrix.rs new file mode 100644 index 00000000..70e1dbfe --- /dev/null +++ b/src/solution/s0378_kth_smallest_element_in_a_sorted_matrix.rs @@ -0,0 +1,66 @@ +/** + * [378] Kth Smallest Element in a Sorted Matrix + * + * Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix. + * + * + * Note that it is the kth smallest element in the sorted order, not the kth distinct element. + * + * + * Example: + * + * matrix = [ + * [ 1, 5, 9], + * [10, 11, 13], + * [12, 13, 15] + * ], + * k = 8, + * + * return 13. + * + * + * + * Note:
+ * You may assume k is always valid, 1 ≤ k ≤ n^2. + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn kth_smallest(matrix: Vec>, k: i32) -> i32 { + use std::collections::BinaryHeap; + // use max heap; TODO: improve + let k = k as usize; + let mut heap = BinaryHeap::new(); + for i in 0..matrix.len() { + for j in 0..matrix[0].len() { + let curr = matrix[i][j]; + if heap.len() < k { + heap.push(curr); + } else { + let mut top = heap.peek_mut().unwrap(); + if curr < *top { + *top = curr; + } + } + } + } + heap.pop().unwrap() + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_378() { + println!( + "{}", + Solution::kth_smallest(vec![vec![1, 5, 9], vec![10, 11, 13], vec![12, 13, 15]], 8) + ) + } +} From 1d78b5d3dc96bfb5601b62c70a9fa53629629ca7 Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 16 Feb 2020 11:21:39 +0800 Subject: [PATCH 17/31] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e2589f60..3cea9dac 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ ### TODO - [ ] update solutions +- [ ] update algorithms - [ ] add multiple solutions - [ ] add function to open discuss page - [ ] accept multiple ids From f6a2ca23a4b45dfa7ab5e34649af8df9d86e4444 Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 16 Feb 2020 13:11:07 +0800 Subject: [PATCH 18/31] add quick_sort and heap_sort --- src/algorithm/heap_sort.rs | 54 +++++++++++++++++++++++++++++++++++++ src/algorithm/mod.rs | 2 ++ src/algorithm/quick_sort.rs | 38 ++++++++++++++++++++++++++ src/lib.rs | 3 ++- src/util/mod.rs | 2 ++ src/util/vec.rs | 18 +++++++++++++ 6 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/algorithm/heap_sort.rs create mode 100644 src/algorithm/mod.rs create mode 100644 src/algorithm/quick_sort.rs create mode 100644 src/util/vec.rs diff --git a/src/algorithm/heap_sort.rs b/src/algorithm/heap_sort.rs new file mode 100644 index 00000000..08951651 --- /dev/null +++ b/src/algorithm/heap_sort.rs @@ -0,0 +1,54 @@ +use crate::util::vec::*; + +fn heap_sort(v: &mut Vec) { + let mut end = v.len() - 1; + for i in (0..v.len()).rev() { + sink(i, v, end); + } + + while end > 0 { + swap(v, 0, end); + end -= 1; + sink(0, v, end); + } +} + +fn left(i: usize) -> usize { + i * 2 + 1 +} + +fn right(i: usize) -> usize { + left(i) + 1 +} + +fn parent(i: usize) -> usize { + (i - 1) / 2 +} + +fn sink(i: usize, v: &mut Vec, end: usize) { + let left = left(i); + let right = right(i); + let mut bigger = i; + if left <= end && v[left] > v[bigger] { + bigger = left; + } + if right <= end && v[right] > v[bigger] { + bigger = right; + } + if bigger != i { + swap(v, i, bigger); + sink(bigger, v, end); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_heap_sort() { + let mut shuffled = get_shuffled_vec(); + heap_sort(&mut shuffled); + assert_eq!(get_sorted_vec(), shuffled); + } +} diff --git a/src/algorithm/mod.rs b/src/algorithm/mod.rs new file mode 100644 index 00000000..b72aea05 --- /dev/null +++ b/src/algorithm/mod.rs @@ -0,0 +1,2 @@ +mod heap_sort; +mod quick_sort; diff --git a/src/algorithm/quick_sort.rs b/src/algorithm/quick_sort.rs new file mode 100644 index 00000000..958547c2 --- /dev/null +++ b/src/algorithm/quick_sort.rs @@ -0,0 +1,38 @@ +use crate::util::vec::*; + +fn quick_sort(v: &mut Vec, left: i32, right: i32) { + if left >= right { + return; + } + let p = partition(v, left, right); + quick_sort(v, left, p - 1); + quick_sort(v, p + 1, right); +} + +fn partition(v: &mut Vec, left: i32, right: i32) -> i32 { + let value = v[right as usize]; + let mut pivot = left - 1; + for i in left..right { + let i = i as usize; + if v[i] <= value { + pivot += 1; + swap(v, i, pivot as usize); + } + } + pivot += 1; + swap(v, pivot as usize, right as usize); + pivot +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_quick_sort() { + let mut shuffled = get_shuffled_vec(); + let right = shuffled.len() as i32 - 1; + quick_sort(&mut shuffled, 0, right); + assert_eq!(get_sorted_vec(), shuffled); + } +} diff --git a/src/lib.rs b/src/lib.rs index 55b0298f..3017e93b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #[macro_use] pub mod util; -pub mod solution; +pub mod algorithm; pub mod problem; +pub mod solution; diff --git a/src/util/mod.rs b/src/util/mod.rs index 5a3e5744..0d4b855d 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -6,3 +6,5 @@ pub mod vec_string; pub mod tree; #[macro_use] pub mod point; + +pub mod vec; diff --git a/src/util/vec.rs b/src/util/vec.rs new file mode 100644 index 00000000..28149b4f --- /dev/null +++ b/src/util/vec.rs @@ -0,0 +1,18 @@ +use rand::seq::SliceRandom; +use rand::{thread_rng, Rng}; + +pub fn swap(v: &mut Vec, i: usize, j: usize) { + let tmp = v[i]; + v[i] = v[j]; + v[j] = tmp; +} + +pub fn get_sorted_vec() -> Vec { + (0..10).collect() +} + +pub fn get_shuffled_vec() -> Vec { + let mut v = get_sorted_vec(); + v.shuffle(&mut thread_rng()); + v +} From c6ffd36e0c89a68411f06616475388911cae6fef Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 16 Feb 2020 13:45:16 +0800 Subject: [PATCH 19/31] add insertion sort --- src/algorithm/insertion_sort.rs | 25 +++++++++++++++++++++++++ src/algorithm/mod.rs | 1 + 2 files changed, 26 insertions(+) create mode 100644 src/algorithm/insertion_sort.rs diff --git a/src/algorithm/insertion_sort.rs b/src/algorithm/insertion_sort.rs new file mode 100644 index 00000000..e8556a8b --- /dev/null +++ b/src/algorithm/insertion_sort.rs @@ -0,0 +1,25 @@ +use crate::util::vec::*; + +fn insertion_sort(v: &mut Vec) { + for i in 1..v.len() { + let value = v[i]; + let mut j = i as i32 - 1; + while j >= 0 && v[j as usize] > value { + v[j as usize + 1] = v[j as usize]; + j -= 1; + } + v[(j + 1) as usize] = value; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_insertion_sort() { + let mut shuffled = get_shuffled_vec(); + insertion_sort(&mut shuffled); + assert_eq!(get_sorted_vec(), shuffled); + } +} diff --git a/src/algorithm/mod.rs b/src/algorithm/mod.rs index b72aea05..d89807b8 100644 --- a/src/algorithm/mod.rs +++ b/src/algorithm/mod.rs @@ -1,2 +1,3 @@ mod heap_sort; +mod insertion_sort; mod quick_sort; From ec257121e530385d4e53cac200fef633b2f0eae0 Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 16 Feb 2020 18:04:23 +0800 Subject: [PATCH 20/31] solve 386, 388, 390 --- src/solution/mod.rs | 3 + src/solution/s0386_lexicographical_numbers.rs | 45 +++++++++ .../s0388_longest_absolute_file_path.rs | 91 +++++++++++++++++++ src/solution/s0390_elimination_game.rs | 70 ++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 src/solution/s0386_lexicographical_numbers.rs create mode 100644 src/solution/s0388_longest_absolute_file_path.rs create mode 100644 src/solution/s0390_elimination_game.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index 6cc29d19..1f29f81c 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -280,3 +280,6 @@ mod s0373_find_k_pairs_with_smallest_sums; mod s0375_guess_number_higher_or_lower_ii; mod s0377_combination_sum_iv; mod s0378_kth_smallest_element_in_a_sorted_matrix; +mod s0386_lexicographical_numbers; +mod s0388_longest_absolute_file_path; +mod s0390_elimination_game; diff --git a/src/solution/s0386_lexicographical_numbers.rs b/src/solution/s0386_lexicographical_numbers.rs new file mode 100644 index 00000000..560defe6 --- /dev/null +++ b/src/solution/s0386_lexicographical_numbers.rs @@ -0,0 +1,45 @@ +/** + * [386] Lexicographical Numbers + * + * Given an integer n, return 1 - n in lexicographical order. + * + * For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9]. + * + * Please optimize your algorithm to use less time and space. The input size may be as large as 5,000,000. + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn lexical_order(n: i32) -> Vec { + let mut ret = Vec::with_capacity(n as usize); + for i in 1..10 { + Self::helper(i, &mut ret); + } + ret + } + + fn helper(curr: i32, ret: &mut Vec) { + if curr > ret.capacity() as i32 { + return; + } + ret.push(curr); + for i in 0..10 { + Self::helper(curr * 10 + i, ret); + } + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_386() { + println!("{:?}", Solution::lexical_order(13)); + } +} diff --git a/src/solution/s0388_longest_absolute_file_path.rs b/src/solution/s0388_longest_absolute_file_path.rs new file mode 100644 index 00000000..2b3e2f50 --- /dev/null +++ b/src/solution/s0388_longest_absolute_file_path.rs @@ -0,0 +1,91 @@ +/** + * [388] Longest Absolute File Path + * + * Suppose we abstract our file system by a string in the following manner: + * + * The string "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" represents: + * + * dir + * subdir1 + * subdir2 + * file.ext + * + * + * The directory dir contains an empty sub-directory subdir1 and a sub-directory subdir2 containing a file file.ext. + * + * The string "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" represents: + * + * dir + * subdir1 + * file1.ext + * subsubdir1 + * subdir2 + * subsubdir2 + * file2.ext + * + * + * The directory dir contains two sub-directories subdir1 and subdir2. subdir1 contains a file file1.ext and an empty second-level sub-directory subsubdir1. subdir2 contains a second-level sub-directory subsubdir2 containing a file file2.ext. + * + * We are interested in finding the longest (number of characters) absolute path to a file within our file system. For example, in the second example above, the longest absolute path is "dir/subdir2/subsubdir2/file2.ext", and its length is 32 (not including the double quotes). + * + * Given a string representing the file system in the above format, return the length of the longest absolute path to file in the abstracted file system. If there is no file in the system, return 0. + * + * Note:
+ * + * The name of a file contains at least a . and an extension. + * The name of a directory or sub-directory will not contain a .. + * + * + * + * Time complexity required: O(n) where n is the size of the input string. + * + * Notice that a/aa/aaa/file1.txt is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png. + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn length_longest_path(input: String) -> i32 { + let mut max_len = 0_usize; + // store previous parts' lengths + let mut stack = vec![]; + for path in input.split("\n") { + let level = path.rfind('\t'); + let level = if level.is_none() { + 0 + } else { + level.unwrap() + 1 + }; + let curr_len; + if level == 0 { + // root + curr_len = path.len(); + // remove previous roots + stack.clear(); + } else { + while stack.len() > level { + // remove unrelated previous parts + stack.pop(); + } + // prev length + curr_total_len - tabs + '/' + curr_len = stack.last().unwrap() + path.len() - level + 1; + } + stack.push(curr_len); + if path.contains('.') { + max_len = max_len.max(curr_len); + } + } + max_len as i32 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_388() {} +} diff --git a/src/solution/s0390_elimination_game.rs b/src/solution/s0390_elimination_game.rs new file mode 100644 index 00000000..a40db935 --- /dev/null +++ b/src/solution/s0390_elimination_game.rs @@ -0,0 +1,70 @@ +/** + * [390] Elimination Game + * + * + * There is a list of sorted integers from 1 to n. Starting from left to right, remove the first number and every other number afterward until you reach the end of the list. + * + * Repeat the previous step again, but this time from right to left, remove the right most number and every other number from the remaining numbers. + * + * We keep repeating the steps again, alternating left to right and right to left, until a single number remains. + * + * Find the last number that remains starting with a list of length n. + * + * Example: + * + * Input: + * n = 9, + * 1 2 3 4 5 6 7 8 9 + * 2 4 6 8 + * 2 6 + * 6 + * + * Output: + * 6 + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn last_remaining(n: i32) -> i32 { + Self::left(n) + } + + pub fn left(n: i32) -> i32 { + if n == 1 { + return 1; + } + if n % 2 == 1 { + 2 * Self::right((n - 1) / 2) + } else { + 2 * Self::right(n / 2) + } + } + + pub fn right(n: i32) -> i32 { + if n == 1 { + return 1; + } + if n % 2 == 1 { + 2 * Self::left((n - 1) / 2) + } else { + // add 1 to all elements, then minus 1 from the result + 2 * Self::left(n / 2) - 1 + } + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_390() { + println!("{}", Solution::last_remaining(9)); + } +} From 4d34c881204141e12dc886ebdbd22906e988a9de Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 16 Feb 2020 19:08:00 +0800 Subject: [PATCH 21/31] solve 393 --- src/solution/mod.rs | 1 + src/solution/s0393_utf_8_validation.rs | 100 +++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/solution/s0393_utf_8_validation.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index 1f29f81c..abbabae7 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -283,3 +283,4 @@ mod s0378_kth_smallest_element_in_a_sorted_matrix; mod s0386_lexicographical_numbers; mod s0388_longest_absolute_file_path; mod s0390_elimination_game; +mod s0393_utf_8_validation; diff --git a/src/solution/s0393_utf_8_validation.rs b/src/solution/s0393_utf_8_validation.rs new file mode 100644 index 00000000..013abd59 --- /dev/null +++ b/src/solution/s0393_utf_8_validation.rs @@ -0,0 +1,100 @@ +/** + * [393] UTF-8 Validation + * + * A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules: + *
    + * For 1-byte character, the first bit is a 0, followed by its unicode code. + * For n-bytes character, the first n-bits are all one's, the n+1 bit is 0, followed by n-1 bytes with most significant 2 bits being 10. + *
+ * This is how the UTF-8 encoding would work: + * + * Char. number range | UTF-8 octet sequence + * (hexadecimal) | (binary) + * --------------------+--------------------------------------------- + * 0000 0000-0000 007F | 0xxxxxxx + * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * + * Given an array of integers representing the data, return whether it is a valid utf-8 encoding. + * + * + * Note:
+ * The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data. + * + * + * + * Example 1: + * + * data = [197, 130, 1], which represents the octet sequence: 11000101 10000010 00000001. + * + * Return true. + * It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte character. + * + * + * + * + * Example 2: + * + * data = [235, 140, 4], which represented the octet sequence: 11101011 10001100 00000100. + * + * Return false. + * The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes character. + * The next byte is a continuation byte which starts with 10 and that's correct. + * But the second continuation byte does not start with 10, so it is invalid. + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn valid_utf8(data: Vec) -> bool { + let mut mask_last_8 = 0b1111_1111; + let ascii_limit = 0b1000_0000; + let mut utf8_folling_bytes = 0; + for num in data.iter().rev() { + let num = *num & mask_last_8; + if num < ascii_limit { + continue; + } + // if gets here, the 8th bit must be 1 + if num & 0b0100_0000 == 0 { + // the 7th bit is 0, utf8 following byte + utf8_folling_bytes += 1; + if utf8_folling_bytes == 4 { + return false; + } + continue; + } + // utf8 starting byte + let mut ones_before_zero = 0; + for i in (0..8).rev() { + if num & (1 << i) > 0 { + ones_before_zero += 1; + } else { + break; + } + } + if ones_before_zero - 1 != utf8_folling_bytes { + return false; + } + utf8_folling_bytes = 0; + } + utf8_folling_bytes == 0 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_393() { + println!("{}", Solution::valid_utf8(vec![145])); + } +} From a93dbd1e7a9de88a6392d5d586edd3437f0f4a41 Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 16 Feb 2020 22:49:06 +0800 Subject: [PATCH 22/31] solve 394 --- src/solution/mod.rs | 1 + src/solution/s0394_decode_string.rs | 64 +++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/solution/s0394_decode_string.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index abbabae7..1570df24 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -284,3 +284,4 @@ mod s0386_lexicographical_numbers; mod s0388_longest_absolute_file_path; mod s0390_elimination_game; mod s0393_utf_8_validation; +mod s0394_decode_string; diff --git a/src/solution/s0394_decode_string.rs b/src/solution/s0394_decode_string.rs new file mode 100644 index 00000000..9d9b2f50 --- /dev/null +++ b/src/solution/s0394_decode_string.rs @@ -0,0 +1,64 @@ +/** + * [394] Decode String + * + * Given an encoded string, return its decoded string. + * The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer. + * You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc. + * Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there won't be input like 3a or 2[4]. + * Examples: + * + * s = "3[a]2[bc]", return "aaabcbc". + * s = "3[a2[c]]", return "accaccacc". + * s = "2[abc]3[cd]ef", return "abcabccdcdcdef". + * + * + * + */ +pub struct Solution {} + +// submission codes start here + +impl Solution { + pub fn decode_string(s: String) -> String { + let mut stack = vec![]; + for c in s.chars() { + if c != ']' { + stack.push(c); + } else { + println!("{:?}", stack); + let mut pattern = String::new(); + while *stack.last().unwrap() != '[' { + pattern.push(stack.pop().unwrap()); + } + pattern = pattern.chars().rev().collect(); + stack.pop(); + let mut count = String::new(); + while !stack.is_empty() && stack.last().unwrap().is_numeric() { + count.push(stack.pop().unwrap()); + } + count = count.chars().rev().collect(); + let mut curr = String::new(); + for _ in 0..count.parse().unwrap() { + curr.push_str(&pattern); + } + stack.append(&mut curr.chars().collect()); + } + } + stack.iter().collect() + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_394() { + println!( + "{}", + Solution::decode_string(String::from("3[z]2[2[y]pq4[2[jk]e1[f]]]ef")) + ); + } +} From b9329711963b67e9e4501f62d8acf6d7d5c157dc Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 16 Feb 2020 22:49:59 +0800 Subject: [PATCH 23/31] fix --- src/solution/s0394_decode_string.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/solution/s0394_decode_string.rs b/src/solution/s0394_decode_string.rs index 9d9b2f50..c5734954 100644 --- a/src/solution/s0394_decode_string.rs +++ b/src/solution/s0394_decode_string.rs @@ -25,7 +25,6 @@ impl Solution { if c != ']' { stack.push(c); } else { - println!("{:?}", stack); let mut pattern = String::new(); while *stack.last().unwrap() != '[' { pattern.push(stack.pop().unwrap()); From d12c073cf8536186057dc3c719e1f9776e5df3ab Mon Sep 17 00:00:00 2001 From: songyzh Date: Mon, 24 Feb 2020 20:34:46 +0800 Subject: [PATCH 24/31] add discuss link --- src/solution/s0318_maximum_product_of_word_lengths.rs | 3 +++ src/solution/s0319_bulb_switcher.rs | 3 +++ src/solution/s0322_coin_change.rs | 3 +++ src/solution/s0326_power_of_three.rs | 3 +++ src/solution/s0328_odd_even_linked_list.rs | 3 +++ .../s0331_verify_preorder_serialization_of_a_binary_tree.rs | 3 +++ src/solution/s0337_house_robber_iii.rs | 3 +++ src/solution/s0343_integer_break.rs | 3 +++ src/solution/s0344_reverse_string.rs | 3 +++ src/solution/s0345_reverse_vowels_of_a_string.rs | 3 +++ src/solution/s0347_top_k_frequent_elements.rs | 3 +++ src/solution/s0349_intersection_of_two_arrays.rs | 3 +++ src/solution/s0350_intersection_of_two_arrays_ii.rs | 3 +++ src/solution/s0357_count_numbers_with_unique_digits.rs | 3 +++ src/solution/s0367_valid_perfect_square.rs | 3 +++ src/solution/s0368_largest_divisible_subset.rs | 3 +++ src/solution/s0371_sum_of_two_integers.rs | 3 +++ src/solution/s0373_find_k_pairs_with_smallest_sums.rs | 3 +++ src/solution/s0375_guess_number_higher_or_lower_ii.rs | 3 +++ src/solution/s0377_combination_sum_iv.rs | 3 +++ src/solution/s0378_kth_smallest_element_in_a_sorted_matrix.rs | 3 +++ src/solution/s0383_ransom_note.rs | 3 +++ src/solution/s0386_lexicographical_numbers.rs | 3 +++ src/solution/s0387_first_unique_character_in_a_string.rs | 3 +++ src/solution/s0388_longest_absolute_file_path.rs | 3 +++ src/solution/s0390_elimination_game.rs | 3 +++ src/solution/s0393_utf_8_validation.rs | 3 +++ src/solution/s0394_decode_string.rs | 3 +++ src/solution/s0409_longest_palindrome.rs | 3 +++ src/solution/s0412_fizz_buzz.rs | 3 +++ src/solution/s0414_third_maximum_number.rs | 3 +++ src/solution/s0415_add_strings.rs | 3 +++ src/solution/s0434_number_of_segments_in_a_string.rs | 3 +++ src/solution/s0437_path_sum_iii.rs | 3 +++ src/solution/s0441_arranging_coins.rs | 3 +++ src/solution/s0443_string_compression.rs | 3 +++ src/solution/s0447_number_of_boomerangs.rs | 3 +++ src/solution/s0448_find_all_numbers_disappeared_in_an_array.rs | 3 +++ src/solution/s0453_minimum_moves_to_equal_array_elements.rs | 3 +++ src/solution/s0455_assign_cookies.rs | 3 +++ src/solution/s0459_repeated_substring_pattern.rs | 3 +++ src/solution/s0461_hamming_distance.rs | 3 +++ src/solution/s0463_island_perimeter.rs | 3 +++ src/solution/s0475_heaters.rs | 3 +++ src/solution/s0476_number_complement.rs | 3 +++ src/solution/s0482_license_key_formatting.rs | 3 +++ src/solution/s0485_max_consecutive_ones.rs | 3 +++ src/solution/s0492_construct_the_rectangle.rs | 3 +++ src/solution/s0496_next_greater_element_i.rs | 3 +++ src/solution/s0500_keyboard_row.rs | 3 +++ 50 files changed, 150 insertions(+) diff --git a/src/solution/s0318_maximum_product_of_word_lengths.rs b/src/solution/s0318_maximum_product_of_word_lengths.rs index c9ac8b46..d26851d2 100644 --- a/src/solution/s0318_maximum_product_of_word_lengths.rs +++ b/src/solution/s0318_maximum_product_of_word_lengths.rs @@ -28,6 +28,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/maximum-product-of-word-lengths/ +// discuss: https://leetcode.com/problems/maximum-product-of-word-lengths/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0319_bulb_switcher.rs b/src/solution/s0319_bulb_switcher.rs index a5ad315f..8e6780bb 100644 --- a/src/solution/s0319_bulb_switcher.rs +++ b/src/solution/s0319_bulb_switcher.rs @@ -20,6 +20,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/bulb-switcher/ +// discuss: https://leetcode.com/problems/bulb-switcher/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0322_coin_change.rs b/src/solution/s0322_coin_change.rs index 08cad772..8d3d3f26 100644 --- a/src/solution/s0322_coin_change.rs +++ b/src/solution/s0322_coin_change.rs @@ -23,6 +23,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/coin-change/ +// discuss: https://leetcode.com/problems/coin-change/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0326_power_of_three.rs b/src/solution/s0326_power_of_three.rs index 6fa7467d..6f2671c9 100644 --- a/src/solution/s0326_power_of_three.rs +++ b/src/solution/s0326_power_of_three.rs @@ -33,6 +33,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/power-of-three/ +// discuss: https://leetcode.com/problems/power-of-three/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0328_odd_even_linked_list.rs b/src/solution/s0328_odd_even_linked_list.rs index 2bc0cc03..b9975b25 100644 --- a/src/solution/s0328_odd_even_linked_list.rs +++ b/src/solution/s0328_odd_even_linked_list.rs @@ -30,6 +30,9 @@ pub struct Solution {} use crate::util::linked_list::{to_list, ListNode}; +// problem: https://leetcode.com/problems/odd-even-linked-list/ +// discuss: https://leetcode.com/problems/odd-even-linked-list/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here // Definition for singly-linked list. diff --git a/src/solution/s0331_verify_preorder_serialization_of_a_binary_tree.rs b/src/solution/s0331_verify_preorder_serialization_of_a_binary_tree.rs index 93129554..a94d912f 100644 --- a/src/solution/s0331_verify_preorder_serialization_of_a_binary_tree.rs +++ b/src/solution/s0331_verify_preorder_serialization_of_a_binary_tree.rs @@ -42,6 +42,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/ +// discuss: https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0337_house_robber_iii.rs b/src/solution/s0337_house_robber_iii.rs index 9f8b158d..e80a7c21 100644 --- a/src/solution/s0337_house_robber_iii.rs +++ b/src/solution/s0337_house_robber_iii.rs @@ -37,6 +37,9 @@ pub struct Solution {} use crate::util::tree::{to_tree, TreeNode}; +// problem: https://leetcode.com/problems/house-robber-iii/ +// discuss: https://leetcode.com/problems/house-robber-iii/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here // Definition for a binary tree node. diff --git a/src/solution/s0343_integer_break.rs b/src/solution/s0343_integer_break.rs index 6b59b3ee..940ea360 100644 --- a/src/solution/s0343_integer_break.rs +++ b/src/solution/s0343_integer_break.rs @@ -25,6 +25,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/integer-break/ +// discuss: https://leetcode.com/problems/integer-break/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0344_reverse_string.rs b/src/solution/s0344_reverse_string.rs index a3cd9d8e..7e583b08 100644 --- a/src/solution/s0344_reverse_string.rs +++ b/src/solution/s0344_reverse_string.rs @@ -29,6 +29,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/reverse-string/ +// discuss: https://leetcode.com/problems/reverse-string/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0345_reverse_vowels_of_a_string.rs b/src/solution/s0345_reverse_vowels_of_a_string.rs index 28b4690a..58288f17 100644 --- a/src/solution/s0345_reverse_vowels_of_a_string.rs +++ b/src/solution/s0345_reverse_vowels_of_a_string.rs @@ -26,6 +26,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/reverse-vowels-of-a-string/ +// discuss: https://leetcode.com/problems/reverse-vowels-of-a-string/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0347_top_k_frequent_elements.rs b/src/solution/s0347_top_k_frequent_elements.rs index 64a40e53..110a51ad 100644 --- a/src/solution/s0347_top_k_frequent_elements.rs +++ b/src/solution/s0347_top_k_frequent_elements.rs @@ -28,6 +28,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/top-k-frequent-elements/ +// discuss: https://leetcode.com/problems/top-k-frequent-elements/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0349_intersection_of_two_arrays.rs b/src/solution/s0349_intersection_of_two_arrays.rs index 7f8063f5..a65e60c0 100644 --- a/src/solution/s0349_intersection_of_two_arrays.rs +++ b/src/solution/s0349_intersection_of_two_arrays.rs @@ -32,6 +32,9 @@ use std::hash::Hash; */ pub struct Solution {} +// problem: https://leetcode.com/problems/intersection-of-two-arrays/ +// discuss: https://leetcode.com/problems/intersection-of-two-arrays/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0350_intersection_of_two_arrays_ii.rs b/src/solution/s0350_intersection_of_two_arrays_ii.rs index 101916a3..4e29939a 100644 --- a/src/solution/s0350_intersection_of_two_arrays_ii.rs +++ b/src/solution/s0350_intersection_of_two_arrays_ii.rs @@ -36,6 +36,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/intersection-of-two-arrays-ii/ +// discuss: https://leetcode.com/problems/intersection-of-two-arrays-ii/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0357_count_numbers_with_unique_digits.rs b/src/solution/s0357_count_numbers_with_unique_digits.rs index cc4a5f61..73f25fe8 100644 --- a/src/solution/s0357_count_numbers_with_unique_digits.rs +++ b/src/solution/s0357_count_numbers_with_unique_digits.rs @@ -16,6 +16,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/count-numbers-with-unique-digits/ +// discuss: https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0367_valid_perfect_square.rs b/src/solution/s0367_valid_perfect_square.rs index e9f99ab7..d6447ff7 100644 --- a/src/solution/s0367_valid_perfect_square.rs +++ b/src/solution/s0367_valid_perfect_square.rs @@ -25,6 +25,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/valid-perfect-square/ +// discuss: https://leetcode.com/problems/valid-perfect-square/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0368_largest_divisible_subset.rs b/src/solution/s0368_largest_divisible_subset.rs index 85ce6e8d..782778a4 100644 --- a/src/solution/s0368_largest_divisible_subset.rs +++ b/src/solution/s0368_largest_divisible_subset.rs @@ -27,6 +27,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/largest-divisible-subset/ +// discuss: https://leetcode.com/problems/largest-divisible-subset/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0371_sum_of_two_integers.rs b/src/solution/s0371_sum_of_two_integers.rs index ef8f48b9..c28cfba9 100644 --- a/src/solution/s0371_sum_of_two_integers.rs +++ b/src/solution/s0371_sum_of_two_integers.rs @@ -24,6 +24,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/sum-of-two-integers/ +// discuss: https://leetcode.com/problems/sum-of-two-integers/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0373_find_k_pairs_with_smallest_sums.rs b/src/solution/s0373_find_k_pairs_with_smallest_sums.rs index 4c11927e..544e0728 100644 --- a/src/solution/s0373_find_k_pairs_with_smallest_sums.rs +++ b/src/solution/s0373_find_k_pairs_with_smallest_sums.rs @@ -34,6 +34,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/find-k-pairs-with-smallest-sums/ +// discuss: https://leetcode.com/problems/find-k-pairs-with-smallest-sums/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0375_guess_number_higher_or_lower_ii.rs b/src/solution/s0375_guess_number_higher_or_lower_ii.rs index 9903e884..70691411 100644 --- a/src/solution/s0375_guess_number_higher_or_lower_ii.rs +++ b/src/solution/s0375_guess_number_higher_or_lower_ii.rs @@ -27,6 +27,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/guess-number-higher-or-lower-ii/ +// discuss: https://leetcode.com/problems/guess-number-higher-or-lower-ii/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0377_combination_sum_iv.rs b/src/solution/s0377_combination_sum_iv.rs index 1d693113..a6bc2cd4 100644 --- a/src/solution/s0377_combination_sum_iv.rs +++ b/src/solution/s0377_combination_sum_iv.rs @@ -36,6 +36,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/combination-sum-iv/ +// discuss: https://leetcode.com/problems/combination-sum-iv/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0378_kth_smallest_element_in_a_sorted_matrix.rs b/src/solution/s0378_kth_smallest_element_in_a_sorted_matrix.rs index 70e1dbfe..ae1f7eb0 100644 --- a/src/solution/s0378_kth_smallest_element_in_a_sorted_matrix.rs +++ b/src/solution/s0378_kth_smallest_element_in_a_sorted_matrix.rs @@ -25,6 +25,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/ +// discuss: https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0383_ransom_note.rs b/src/solution/s0383_ransom_note.rs index 07632028..d21b5069 100644 --- a/src/solution/s0383_ransom_note.rs +++ b/src/solution/s0383_ransom_note.rs @@ -24,6 +24,9 @@ use std::collections::HashMap; */ pub struct Solution {} +// problem: https://leetcode.com/problems/ransom-note/ +// discuss: https://leetcode.com/problems/ransom-note/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0386_lexicographical_numbers.rs b/src/solution/s0386_lexicographical_numbers.rs index 560defe6..cc92bc09 100644 --- a/src/solution/s0386_lexicographical_numbers.rs +++ b/src/solution/s0386_lexicographical_numbers.rs @@ -10,6 +10,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/lexicographical-numbers/ +// discuss: https://leetcode.com/problems/lexicographical-numbers/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0387_first_unique_character_in_a_string.rs b/src/solution/s0387_first_unique_character_in_a_string.rs index e229c412..7cada59d 100644 --- a/src/solution/s0387_first_unique_character_in_a_string.rs +++ b/src/solution/s0387_first_unique_character_in_a_string.rs @@ -20,6 +20,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/first-unique-character-in-a-string/ +// discuss: https://leetcode.com/problems/first-unique-character-in-a-string/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0388_longest_absolute_file_path.rs b/src/solution/s0388_longest_absolute_file_path.rs index 2b3e2f50..9924e433 100644 --- a/src/solution/s0388_longest_absolute_file_path.rs +++ b/src/solution/s0388_longest_absolute_file_path.rs @@ -43,6 +43,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/longest-absolute-file-path/ +// discuss: https://leetcode.com/problems/longest-absolute-file-path/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0390_elimination_game.rs b/src/solution/s0390_elimination_game.rs index a40db935..38c763e4 100644 --- a/src/solution/s0390_elimination_game.rs +++ b/src/solution/s0390_elimination_game.rs @@ -26,6 +26,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/elimination-game/ +// discuss: https://leetcode.com/problems/elimination-game/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0393_utf_8_validation.rs b/src/solution/s0393_utf_8_validation.rs index 013abd59..d8a29bb0 100644 --- a/src/solution/s0393_utf_8_validation.rs +++ b/src/solution/s0393_utf_8_validation.rs @@ -48,6 +48,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/utf-8-validation/ +// discuss: https://leetcode.com/problems/utf-8-validation/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0394_decode_string.rs b/src/solution/s0394_decode_string.rs index c5734954..eefddde8 100644 --- a/src/solution/s0394_decode_string.rs +++ b/src/solution/s0394_decode_string.rs @@ -16,6 +16,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/decode-string/ +// discuss: https://leetcode.com/problems/decode-string/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0409_longest_palindrome.rs b/src/solution/s0409_longest_palindrome.rs index dc278265..b4560e30 100644 --- a/src/solution/s0409_longest_palindrome.rs +++ b/src/solution/s0409_longest_palindrome.rs @@ -24,6 +24,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/longest-palindrome/ +// discuss: https://leetcode.com/problems/longest-palindrome/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0412_fizz_buzz.rs b/src/solution/s0412_fizz_buzz.rs index e68fa06f..bf97a603 100644 --- a/src/solution/s0412_fizz_buzz.rs +++ b/src/solution/s0412_fizz_buzz.rs @@ -32,6 +32,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/fizz-buzz/ +// discuss: https://leetcode.com/problems/fizz-buzz/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0414_third_maximum_number.rs b/src/solution/s0414_third_maximum_number.rs index 4b4c7219..763e8c7a 100644 --- a/src/solution/s0414_third_maximum_number.rs +++ b/src/solution/s0414_third_maximum_number.rs @@ -36,6 +36,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/third-maximum-number/ +// discuss: https://leetcode.com/problems/third-maximum-number/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0415_add_strings.rs b/src/solution/s0415_add_strings.rs index d3ad1386..3e032223 100644 --- a/src/solution/s0415_add_strings.rs +++ b/src/solution/s0415_add_strings.rs @@ -14,6 +14,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/add-strings/ +// discuss: https://leetcode.com/problems/add-strings/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0434_number_of_segments_in_a_string.rs b/src/solution/s0434_number_of_segments_in_a_string.rs index 7c9bb060..aad4c723 100644 --- a/src/solution/s0434_number_of_segments_in_a_string.rs +++ b/src/solution/s0434_number_of_segments_in_a_string.rs @@ -14,6 +14,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/number-of-segments-in-a-string/ +// discuss: https://leetcode.com/problems/number-of-segments-in-a-string/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0437_path_sum_iii.rs b/src/solution/s0437_path_sum_iii.rs index 08057bd3..bc17265b 100644 --- a/src/solution/s0437_path_sum_iii.rs +++ b/src/solution/s0437_path_sum_iii.rs @@ -33,6 +33,9 @@ pub struct Solution {} use crate::util::tree::{to_tree, TreeNode}; +// problem: https://leetcode.com/problems/path-sum-iii/ +// discuss: https://leetcode.com/problems/path-sum-iii/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here // Definition for a binary tree node. diff --git a/src/solution/s0441_arranging_coins.rs b/src/solution/s0441_arranging_coins.rs index 186daf15..0b86dabe 100644 --- a/src/solution/s0441_arranging_coins.rs +++ b/src/solution/s0441_arranging_coins.rs @@ -36,6 +36,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/arranging-coins/ +// discuss: https://leetcode.com/problems/arranging-coins/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0443_string_compression.rs b/src/solution/s0443_string_compression.rs index 1bb43d12..03acde8e 100644 --- a/src/solution/s0443_string_compression.rs +++ b/src/solution/s0443_string_compression.rs @@ -70,6 +70,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/string-compression/ +// discuss: https://leetcode.com/problems/string-compression/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0447_number_of_boomerangs.rs b/src/solution/s0447_number_of_boomerangs.rs index 01c710c0..11bf5b00 100644 --- a/src/solution/s0447_number_of_boomerangs.rs +++ b/src/solution/s0447_number_of_boomerangs.rs @@ -23,6 +23,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/number-of-boomerangs/ +// discuss: https://leetcode.com/problems/number-of-boomerangs/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0448_find_all_numbers_disappeared_in_an_array.rs b/src/solution/s0448_find_all_numbers_disappeared_in_an_array.rs index c2409604..de1dc323 100644 --- a/src/solution/s0448_find_all_numbers_disappeared_in_an_array.rs +++ b/src/solution/s0448_find_all_numbers_disappeared_in_an_array.rs @@ -19,6 +19,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/ +// discuss: https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0453_minimum_moves_to_equal_array_elements.rs b/src/solution/s0453_minimum_moves_to_equal_array_elements.rs index ba921c75..9d7df77f 100644 --- a/src/solution/s0453_minimum_moves_to_equal_array_elements.rs +++ b/src/solution/s0453_minimum_moves_to_equal_array_elements.rs @@ -20,6 +20,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/minimum-moves-to-equal-array-elements/ +// discuss: https://leetcode.com/problems/minimum-moves-to-equal-array-elements/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0455_assign_cookies.rs b/src/solution/s0455_assign_cookies.rs index f0d681ba..183bbafc 100644 --- a/src/solution/s0455_assign_cookies.rs +++ b/src/solution/s0455_assign_cookies.rs @@ -36,6 +36,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/assign-cookies/ +// discuss: https://leetcode.com/problems/assign-cookies/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0459_repeated_substring_pattern.rs b/src/solution/s0459_repeated_substring_pattern.rs index f1ed8682..2524eb2f 100644 --- a/src/solution/s0459_repeated_substring_pattern.rs +++ b/src/solution/s0459_repeated_substring_pattern.rs @@ -31,6 +31,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/repeated-substring-pattern/ +// discuss: https://leetcode.com/problems/repeated-substring-pattern/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0461_hamming_distance.rs b/src/solution/s0461_hamming_distance.rs index 2d6bc3e8..d93a02ba 100644 --- a/src/solution/s0461_hamming_distance.rs +++ b/src/solution/s0461_hamming_distance.rs @@ -26,6 +26,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/hamming-distance/ +// discuss: https://leetcode.com/problems/hamming-distance/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0463_island_perimeter.rs b/src/solution/s0463_island_perimeter.rs index eb63063e..350588e6 100644 --- a/src/solution/s0463_island_perimeter.rs +++ b/src/solution/s0463_island_perimeter.rs @@ -28,6 +28,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/island-perimeter/ +// discuss: https://leetcode.com/problems/island-perimeter/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0475_heaters.rs b/src/solution/s0475_heaters.rs index e661f1aa..364078bd 100644 --- a/src/solution/s0475_heaters.rs +++ b/src/solution/s0475_heaters.rs @@ -41,6 +41,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/heaters/ +// discuss: https://leetcode.com/problems/heaters/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0476_number_complement.rs b/src/solution/s0476_number_complement.rs index f7d21888..0f8c00b0 100644 --- a/src/solution/s0476_number_complement.rs +++ b/src/solution/s0476_number_complement.rs @@ -28,6 +28,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/number-complement/ +// discuss: https://leetcode.com/problems/number-complement/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0482_license_key_formatting.rs b/src/solution/s0482_license_key_formatting.rs index 0e6cce25..8f2277bd 100644 --- a/src/solution/s0482_license_key_formatting.rs +++ b/src/solution/s0482_license_key_formatting.rs @@ -39,6 +39,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/license-key-formatting/ +// discuss: https://leetcode.com/problems/license-key-formatting/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0485_max_consecutive_ones.rs b/src/solution/s0485_max_consecutive_ones.rs index 9348962c..89e1a47e 100644 --- a/src/solution/s0485_max_consecutive_ones.rs +++ b/src/solution/s0485_max_consecutive_ones.rs @@ -21,6 +21,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/max-consecutive-ones/ +// discuss: https://leetcode.com/problems/max-consecutive-ones/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0492_construct_the_rectangle.rs b/src/solution/s0492_construct_the_rectangle.rs index 94074032..9dfa8773 100644 --- a/src/solution/s0492_construct_the_rectangle.rs +++ b/src/solution/s0492_construct_the_rectangle.rs @@ -29,6 +29,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/construct-the-rectangle/ +// discuss: https://leetcode.com/problems/construct-the-rectangle/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0496_next_greater_element_i.rs b/src/solution/s0496_next_greater_element_i.rs index a58b04db..6cd0d322 100644 --- a/src/solution/s0496_next_greater_element_i.rs +++ b/src/solution/s0496_next_greater_element_i.rs @@ -40,6 +40,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/next-greater-element-i/ +// discuss: https://leetcode.com/problems/next-greater-element-i/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { diff --git a/src/solution/s0500_keyboard_row.rs b/src/solution/s0500_keyboard_row.rs index 0a7d6aed..96f6afa2 100644 --- a/src/solution/s0500_keyboard_row.rs +++ b/src/solution/s0500_keyboard_row.rs @@ -27,6 +27,9 @@ */ pub struct Solution {} +// problem: https://leetcode.com/problems/keyboard-row/ +// discuss: https://leetcode.com/problems/keyboard-row/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here use std::collections::HashMap; From c40c5abffd066e3532f8d7fbc05f323e84f42f62 Mon Sep 17 00:00:00 2001 From: songyzh Date: Tue, 25 Feb 2020 22:59:24 +0800 Subject: [PATCH 25/31] solve 395 --- src/solution/mod.rs | 1 + ...ng_with_at_least_k_repeating_characters.rs | 86 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/solution/s0395_longest_substring_with_at_least_k_repeating_characters.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index cd5f8b54..6e384827 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -285,3 +285,4 @@ mod s0704_binary_search; mod s0969_pancake_sorting; mod s1018_binary_prefix_divisible_by_5; mod s1046_last_stone_weight; +mod s0395_longest_substring_with_at_least_k_repeating_characters; diff --git a/src/solution/s0395_longest_substring_with_at_least_k_repeating_characters.rs b/src/solution/s0395_longest_substring_with_at_least_k_repeating_characters.rs new file mode 100644 index 00000000..4229dbdc --- /dev/null +++ b/src/solution/s0395_longest_substring_with_at_least_k_repeating_characters.rs @@ -0,0 +1,86 @@ +/** + * [395] Longest Substring with At Least K Repeating Characters + * + * + * Find the length of the longest substring T of a given string (consists of lowercase letters only) such that every character in T appears no less than k times. + * + * + * Example 1: + * + * Input: + * s = "aaabb", k = 3 + * + * Output: + * 3 + * + * The longest substring is "aaa", as 'a' is repeated 3 times. + * + * + * + * Example 2: + * + * Input: + * s = "ababbc", k = 2 + * + * Output: + * 5 + * + * The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times. + * + * + */ +pub struct Solution {} + +// problem: https://leetcode.com/problems/longest-substring-with-at-least-k-repeating-characters/ +// discuss: https://leetcode.com/problems/longest-substring-with-at-least-k-repeating-characters/discuss/?currentPage=1&orderBy=most_votes&query= + +// submission codes start here + +impl Solution { + pub fn longest_substring(s: String, k: i32) -> i32 { + if s.len() == 0 { + return 0; + } + if k < 2 { + return s.len() as i32; + } + let chars: Vec = s.chars().collect(); + Self::helper(&chars, 0, s.len(), k) + } + + fn helper(chars: &Vec, left: usize, right: usize, k: i32) -> i32 { + use std::collections::HashMap; + let mut map = HashMap::new(); + for i in left..right { + *map.entry(chars[i]).or_insert(0) += 1; + } + if map.is_empty() { + return 0; + } + if *map.values().min().unwrap() >= k { + return (right - left) as i32; + } + let mut start = left; + let mut ret = 0; + for i in left..right { + if *map.get(&chars[i]).unwrap() < k { + ret = ret.max(Self::helper(chars, start, i, k)); + start = i + 1; + } + } + ret.max(Self::helper(chars, start, right, k)) + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_395() { + println!("{}", Solution::longest_substring("weitong".to_string(), 3)); + println!("{}", Solution::longest_substring("ababbc".to_string(), 2)); + } +} From 05f6e29fe80b86209fffc8a3c53d50e239708546 Mon Sep 17 00:00:00 2001 From: songyzh Date: Thu, 27 Feb 2020 16:53:53 +0800 Subject: [PATCH 26/31] solve 396, 399, 400 --- src/solution/mod.rs | 3 + src/solution/s0396_rotate_function.rs | 74 +++++++++++ src/solution/s0399_evaluate_division.rs | 160 ++++++++++++++++++++++++ src/solution/s0400_nth_digit.rs | 76 +++++++++++ 4 files changed, 313 insertions(+) create mode 100644 src/solution/s0396_rotate_function.rs create mode 100644 src/solution/s0399_evaluate_division.rs create mode 100644 src/solution/s0400_nth_digit.rs diff --git a/src/solution/mod.rs b/src/solution/mod.rs index 6e384827..3bec2a2f 100644 --- a/src/solution/mod.rs +++ b/src/solution/mod.rs @@ -286,3 +286,6 @@ mod s0969_pancake_sorting; mod s1018_binary_prefix_divisible_by_5; mod s1046_last_stone_weight; mod s0395_longest_substring_with_at_least_k_repeating_characters; +mod s0396_rotate_function; +mod s0399_evaluate_division; +mod s0400_nth_digit; diff --git a/src/solution/s0396_rotate_function.rs b/src/solution/s0396_rotate_function.rs new file mode 100644 index 00000000..1971bf74 --- /dev/null +++ b/src/solution/s0396_rotate_function.rs @@ -0,0 +1,74 @@ +/** + * [396] Rotate Function + * + * + * Given an array of integers A and let n to be its length. + * + * + * + * Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a "rotation function" F on A as follow: + * + * + * + * F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. + * + * Calculate the maximum value of F(0), F(1), ..., F(n-1). + * + * + * Note:
+ * n is guaranteed to be less than 10^5. + * + * + * Example: + * + * A = [4, 3, 2, 6] + * + * F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25 + * F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16 + * F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23 + * F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26 + * + * So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. + * + * + */ +pub struct Solution {} + +// problem: https://leetcode.com/problems/rotate-function/ +// discuss: https://leetcode.com/problems/rotate-function/discuss/?currentPage=1&orderBy=most_votes&query= + +// submission codes start here + +impl Solution { + pub fn max_rotate_function(a: Vec) -> i32 { + // 0 * a0 + 1 * a_1 + .. + (n - 1) * a_(n - 1) = t0 + // 1 * a0 + 2 * a_1 + .. + 0 * a_(n - 1) = t0 + sum - n * a_(n - 1) + // (n - 1) * a0 + 0 * a_1 + .. + (n - 2) * a_(n - 1) = t_p + sum - n * a_1 + let n = a.len(); + let mut sum = 0; + let mut curr = 0; + for (i, num) in a.iter().enumerate() { + let i = i as i32; + sum += *num; + curr += i * (*num); + } + let mut ret = curr; + for i in (1..n).rev() { + curr = curr + sum - n as i32 * a[i]; + ret = ret.max(curr); + } + ret + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_396() { + println!("{}", Solution::max_rotate_function(vec![4, 3, 2, 6])); + } +} diff --git a/src/solution/s0399_evaluate_division.rs b/src/solution/s0399_evaluate_division.rs new file mode 100644 index 00000000..20394108 --- /dev/null +++ b/src/solution/s0399_evaluate_division.rs @@ -0,0 +1,160 @@ +/** + * [399] Evaluate Division + * + * Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0. + * + * Example:
+ * Given a / b = 2.0, b / c = 3.0.
+ * queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .
+ * return [6.0, 0.5, -1.0, 1.0, -1.0 ]. + * + * The input is: vector> equations, vector& values, vector> queries , where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector. + * + * According to the example above: + * + * + * equations = [ ["a", "b"], ["b", "c"] ], + * values = [2.0, 3.0], + * queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. + * + * + * + * The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction. + * + */ +pub struct Solution {} + +// problem: https://leetcode.com/problems/evaluate-division/ +// discuss: https://leetcode.com/problems/evaluate-division/discuss/?currentPage=1&orderBy=most_votes&query= + +// submission codes start here +use std::collections::HashMap; +use std::collections::HashSet; + +impl Solution { + pub fn calc_equation( + equations: Vec>, + values: Vec, + queries: Vec>, + ) -> Vec { + // TODO reduce lines... + // evaluate all values + let mut graph = HashMap::new(); + for (i, pair) in equations.iter().enumerate() { + let first = &pair[0]; + let second = &pair[1]; + graph.entry(first).or_insert(vec![]).push(i); + graph.entry(second).or_insert(vec![]).push(i); + } + let mut map = HashMap::new(); + let mut tree_no = HashMap::new(); + let mut curr_tree_no = 0; + for i in 0..equations.len() { + Self::helper( + &equations, + &values, + &graph, + &mut map, + &mut tree_no, + &mut curr_tree_no, + &mut HashSet::new(), + i, + ); + } + let mut ret = vec![]; + for pair in queries { + let first = &pair[0]; + let second = &pair[1]; + if !map.contains_key(first) + || !map.contains_key(second) + || (tree_no.get(first).unwrap() != tree_no.get(second).unwrap()) + { + ret.push(-1_f64); + continue; + } + ret.push(*map.get(first).unwrap() / *map.get(second).unwrap()); + } + ret + } + + fn helper<'a>( + equations: &'a Vec>, + values: &Vec, + graph: &HashMap<&String, Vec>, + map: &mut HashMap<&'a String, f64>, + tree_no: &mut HashMap<&'a String, i32>, + curr_tree_no: &mut i32, + evaled_equation_indices: &mut HashSet, + curr_equation_index: usize, + ) { + if evaled_equation_indices.contains(&curr_equation_index) { + return; + } + evaled_equation_indices.insert(curr_equation_index); + let pair = &equations[curr_equation_index]; + let first = &pair[0]; + let second = &pair[1]; + let q = values[curr_equation_index]; + if !map.contains_key(first) && !map.contains_key(second) { + // new graph + *curr_tree_no += 1; + map.insert(first, 1_f64); + tree_no.insert(first, *curr_tree_no); + } + if map.contains_key(first) && !map.contains_key(second) { + map.insert(second, *map.get(first).unwrap() / q); + tree_no.insert(second, *curr_tree_no); + } + if map.contains_key(second) && !map.contains_key(first) { + map.insert(first, *map.get(second).unwrap() * q); + tree_no.insert(first, *curr_tree_no); + } + for i in graph.get(first).unwrap() { + Self::helper( + equations, + values, + graph, + map, + tree_no, + curr_tree_no, + evaled_equation_indices, + *i, + ); + } + for i in graph.get(second).unwrap() { + Self::helper( + equations, + values, + graph, + map, + tree_no, + curr_tree_no, + evaled_equation_indices, + *i, + ); + } + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_399() { + println!( + "{:?}", + Solution::calc_equation( + vec![vec_string!["a", "e"], vec_string!["b", "e"]], + vec![4.0, 3.0], + vec![ + vec_string!["a", "b"], + vec_string!["e", "e"], + vec_string!["x", "x"], + ], + ) + ); + } +} diff --git a/src/solution/s0400_nth_digit.rs b/src/solution/s0400_nth_digit.rs new file mode 100644 index 00000000..fa83877e --- /dev/null +++ b/src/solution/s0400_nth_digit.rs @@ -0,0 +1,76 @@ +/** + * [400] Nth Digit + * + * Find the n^th digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... + * + * Note:
+ * n is positive and will fit within the range of a 32-bit signed integer (n < 2^31). + * + * + * Example 1: + * + * Input: + * 3 + * + * Output: + * 3 + * + * + * + * Example 2: + * + * Input: + * 11 + * + * Output: + * 0 + * + * Explanation: + * The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10. + * + * + */ +pub struct Solution {} + +// problem: https://leetcode.com/problems/nth-digit/ +// discuss: https://leetcode.com/problems/nth-digit/discuss/?currentPage=1&orderBy=most_votes&query= + +// submission codes start here + +impl Solution { + pub fn find_nth_digit(n: i32) -> i32 { + // 1-9 => 9 => 9 + // 10-99 => 90 => 180 + // 100-999 => 900 => 2700 + let mut n = n as i64 - 1; + let mut single_width = 1; + let mut start = 1; + let mut end = start * 10 - 1; + let mut range_width: i64 = (end - start + 1) * single_width; + while n >= range_width { + n -= range_width; + start = end + 1; + end = start * 10 - 1; + single_width += 1; + range_width = (end - start + 1) * single_width; + } + let nums = n / single_width; + start += nums; + n -= nums * single_width; + start.to_string().chars().collect::>()[n as usize] + .to_digit(10) + .unwrap() as i32 + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_400() { + println!("{}", Solution::find_nth_digit(1000000000)); + } +} From 36ce9b0c5570a17a60211c3310860988387e56f6 Mon Sep 17 00:00:00 2001 From: songyzh Date: Fri, 28 Feb 2020 21:43:34 +0800 Subject: [PATCH 27/31] optimize 2, 11, 12, 29, 31 --- src/solution/s0002_add_two_numbers.rs | 62 +++++++------------ .../s0011_container_with_most_water.rs | 43 ++++--------- src/solution/s0012_integer_to_roman.rs | 26 ++++---- src/solution/s0029_divide_two_integers.rs | 47 +++++++++++++- src/solution/s0031_next_permutation.rs | 38 ++++++------ 5 files changed, 113 insertions(+), 103 deletions(-) diff --git a/src/solution/s0002_add_two_numbers.rs b/src/solution/s0002_add_two_numbers.rs index d8bfc2d8..7bc447d0 100644 --- a/src/solution/s0002_add_two_numbers.rs +++ b/src/solution/s0002_add_two_numbers.rs @@ -29,46 +29,32 @@ impl Solution { l1: Option>, l2: Option>, ) -> Option> { - let (mut l1, mut l2) = (l1, l2); - let mut dummy_head = Some(Box::new(ListNode::new(0))); - let mut tail = &mut dummy_head; - let (mut l1_end, mut l2_end, mut overflow) = (false, false, false); - loop { - let lhs = match l1 { - Some(node) => { - l1 = node.next; - node.val - } - None => { - l1_end = true; - 0 - } - }; - let rhs = match l2 { - Some(node) => { - l2 = node.next; - node.val - } - None => { - l2_end = true; - 0 - } - }; - // if l1, l2 end and there is not overflow from previous operation, return the result - if l1_end && l2_end && !overflow { - break dummy_head.unwrap().next; + let mut l1 = l1; + let mut l2 = l2; + let mut dummy = Some(Box::new(ListNode::new(0))); + let mut dummy_ref = dummy.as_mut().unwrap(); + let mut carrier = 0; + while l1.is_some() || l2.is_some() { + let mut v1 = 0; + if l1.is_some() { + v1 = l1.as_ref().unwrap().val; + l1 = l1.unwrap().next; } - let sum = lhs + rhs + if overflow { 1 } else { 0 }; - let sum = if sum >= 10 { - overflow = true; - sum - 10 - } else { - overflow = false; - sum - }; - tail.as_mut().unwrap().next = Some(Box::new(ListNode::new(sum))); - tail = &mut tail.as_mut().unwrap().next + let mut v2 = 0; + if l2.is_some() { + v2 = l2.as_ref().unwrap().val; + l2 = l2.unwrap().next; + } + let sum = v1 + v2 + carrier; + let curr = sum % 10; + carrier = sum / 10; + dummy_ref.next = Some(Box::new(ListNode::new(curr))); + dummy_ref = dummy_ref.next.as_mut().unwrap(); + } + if carrier > 0 { + dummy_ref.next = Some(Box::new(ListNode::new(carrier))); } + dummy.unwrap().next } } diff --git a/src/solution/s0011_container_with_most_water.rs b/src/solution/s0011_container_with_most_water.rs index ae818bac..673d22ac 100644 --- a/src/solution/s0011_container_with_most_water.rs +++ b/src/solution/s0011_container_with_most_water.rs @@ -5,13 +5,13 @@ * * Note: You may not slant the container and n is at least 2. * - * + * * * * * The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49. * - * + * * * Example: * @@ -32,37 +32,20 @@ pub struct Solution {} // Two Pointer: a[0] -> <- a[n-1] impl Solution { pub fn max_area(height: Vec) -> i32 { - let (mut start, mut end) = (0_usize, (height.len() - 1)); - let mut max: i32 = (end - start) as i32 * Solution::min(height[start], height[end]); - let mut curr_area: i32 = 0; - while end - start > 1 { - // move the lower one - if height[start] < height[end] { - start += 1; - if height[start] < height[start - 1] { - continue; - } + let mut ret = 0; + let mut left_index = 0; + let mut right_index = height.len() - 1; + while left_index < right_index { + let width = (right_index - left_index) as i32; + let curr = width * height[left_index].min(height[right_index]); + ret = ret.max(curr); + if height[left_index] > height[right_index] { + right_index -= 1; } else { - end -= 1; - if height[end] < height[end + 1] { - continue; - } - } - curr_area = (end - start) as i32 * Solution::min(height[start], height[end]); - if curr_area > max { - max = curr_area + left_index += 1; } } - max - } - - #[inline(always)] - fn min(i: i32, j: i32) -> i32 { - if i > j { - j - } else { - i - } + ret } } diff --git a/src/solution/s0012_integer_to_roman.rs b/src/solution/s0012_integer_to_roman.rs index b32592c7..2aa96868 100644 --- a/src/solution/s0012_integer_to_roman.rs +++ b/src/solution/s0012_integer_to_roman.rs @@ -61,14 +61,15 @@ */ pub struct Solution {} -// problem: https://leetcode.com/problems/integer-to-roman/ -// discuss: https://leetcode.com/problems/integer-to-roman/discuss/?currentPage=1&orderBy=most_votes&query= - +// problem: https://leetcode.com/problems/integer-to-roman/ +// discuss: https://leetcode.com/problems/integer-to-roman/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { pub fn int_to_roman(num: i32) -> String { - let table: Vec<(i32, &'static str)> = vec![ + let mut num = num; + let lookup = vec![ (1000, "M"), (900, "CM"), (500, "D"), @@ -83,18 +84,15 @@ impl Solution { (4, "IV"), (1, "I"), ]; - - let mut num = num; - let mut sb = String::new(); - for p in table.iter() { - if num >= p.0 { - for _ in 0..(num / p.0) { - sb.push_str(p.1); - } - num = num % p.0 + let mut ret = String::new(); + for (val, rom) in lookup { + if num >= val { + let cnt = num / val; + (0..cnt).map(|_| ret.push_str(rom)).count(); + num %= val; } } - sb + ret } } diff --git a/src/solution/s0029_divide_two_integers.rs b/src/solution/s0029_divide_two_integers.rs index e8f13435..3ad4d9e4 100644 --- a/src/solution/s0029_divide_two_integers.rs +++ b/src/solution/s0029_divide_two_integers.rs @@ -35,9 +35,54 @@ pub struct Solution {} // submission codes start here +use std::i32::MAX; +use std::i32::MIN; + impl Solution { pub fn divide(dividend: i32, divisor: i32) -> i32 { - 0 + let mut dividend = dividend; + let mut divisor = divisor; + if divisor == 1 { + return dividend; + } + // in case divisor == MIN + if divisor == MIN { + if dividend == MIN { + return 1; + } + return 0; + } + // in case dividend == MIN + if dividend == MIN && divisor == -1 { + return MAX; + } + let mut borrow = 0; + if dividend == MIN { + if divisor > 0 { + borrow = -1; + dividend += divisor; + } else { + borrow = 1; + dividend -= divisor; + } + } + let mut ret = 0; + let mut flag = 1; + if dividend > 0 && divisor < 0 || dividend < 0 && divisor > 0 { + flag = -1; + } + dividend = dividend.abs(); + divisor = divisor.abs(); + while dividend >= divisor { + let mut curr_divisor = divisor; + let mut offset = 0; + while curr_divisor << offset > 0 && dividend >= curr_divisor << offset { + ret += 1 << offset; + dividend -= curr_divisor << offset; + offset += 1; + } + } + ret * flag + borrow } } diff --git a/src/solution/s0031_next_permutation.rs b/src/solution/s0031_next_permutation.rs index b448dfa1..9ba3970b 100644 --- a/src/solution/s0031_next_permutation.rs +++ b/src/solution/s0031_next_permutation.rs @@ -23,31 +23,29 @@ pub struct Solution {} impl Solution { pub fn next_permutation(nums: &mut Vec) { - let len = nums.len(); - let mut i = (len - 1) as i32; - let mut prev = -1; - // find the decrement digit from end - while i >= 0 { - if nums[i as usize] < prev { + let mut change_index = None; + for i in (0..nums.len() - 1).rev() { + if nums[i] < nums[i + 1] { + change_index = Some(i); break; } - prev = nums[i as usize]; - i -= 1; } - let mut j = len - 1; - // find the first digit larger than nums[i] - // we can do binary search here to make a slightly improvement - if i >= 0 { - while j > (i as usize) { - if nums[j] > nums[i as usize] { - nums.swap(i as usize, j); - break; - } - j -= 1; + if change_index.is_none() { + nums.sort_unstable(); + return; + } + let change_index = change_index.unwrap(); + let mut successor_index = None; + for i in (change_index + 1..nums.len()).rev() { + if nums[i] > nums[change_index] { + successor_index = Some(i); + break; } } - let slice = &mut nums[((i + 1) as usize)..len]; - slice.reverse(); + let successor_index = successor_index.unwrap(); + nums.swap(change_index, successor_index); + let len = nums.len(); + nums[change_index + 1..len].sort_unstable() } } From 8efddbc5b83725c793f7084ab723d480e31378e5 Mon Sep 17 00:00:00 2001 From: songyzh Date: Sat, 29 Feb 2020 20:49:20 +0800 Subject: [PATCH 28/31] optimize or add solution 24, 34, 39, 43, 48, 50 --- src/solution/s0024_swap_nodes_in_pairs.rs | 12 +++ ...ast_position_of_element_in_sorted_array.rs | 53 ++++++++++++- src/solution/s0039_combination_sum.rs | 33 +++++++- src/solution/s0043_multiply_strings.rs | 77 +++++++++++++++---- src/solution/s0048_rotate_image.rs | 26 ++++++- src/solution/s0050_powx_n.rs | 32 ++++++-- 6 files changed, 202 insertions(+), 31 deletions(-) diff --git a/src/solution/s0024_swap_nodes_in_pairs.rs b/src/solution/s0024_swap_nodes_in_pairs.rs index 4a6deb3e..5af6ddeb 100644 --- a/src/solution/s0024_swap_nodes_in_pairs.rs +++ b/src/solution/s0024_swap_nodes_in_pairs.rs @@ -49,6 +49,18 @@ impl Solution { } dummy_head.unwrap().next } + + pub fn swap_pairs_1(head: Option>) -> Option> { + if head.is_none() || head.as_ref().unwrap().next.is_none() { + return head; + } + let mut head = head; + let mut third = head.as_mut().unwrap().next.as_mut().unwrap().next.take(); + let mut second = head.as_mut().unwrap().next.take(); + head.as_mut().unwrap().next = Self::swap_pairs(third); + second.as_mut().unwrap().next = head; + second + } } // submission codes end diff --git a/src/solution/s0034_find_first_and_last_position_of_element_in_sorted_array.rs b/src/solution/s0034_find_first_and_last_position_of_element_in_sorted_array.rs index eba1c01c..62190608 100644 --- a/src/solution/s0034_find_first_and_last_position_of_element_in_sorted_array.rs +++ b/src/solution/s0034_find_first_and_last_position_of_element_in_sorted_array.rs @@ -27,10 +27,59 @@ pub struct Solution {} // submission codes start here -// TODO impl Solution { pub fn search_range(nums: Vec, target: i32) -> Vec { - vec![] + let search = nums.binary_search(&target); + if search.is_err() { + return vec![-1, -1]; + } + let search = search.unwrap(); + let mut left_most = Self::search_left_most(&nums, target, 0, search - 1); + left_most = if left_most == -1 { + search as i32 + } else { + left_most + }; + let mut right_most = Self::search_right_most(&nums, target, search + 1, nums.len() - 1); + right_most = if right_most == -1 { + search as i32 + } else { + right_most + }; + vec![left_most, right_most] + } + + fn search_left_most(nums: &Vec, target: i32, left: usize, right: usize) -> i32 { + if left > right { + return -1; + } + let search = nums[left..right + 1].binary_search(&target); + if search.is_err() { + return -1; + } + let search = search.unwrap() + left; + let mut left_most = Self::search_left_most(nums, target, left, search - 1); + if left_most == -1 { + search as i32 + } else { + left_most + } + } + fn search_right_most(nums: &Vec, target: i32, left: usize, right: usize) -> i32 { + if left > right { + return -1; + } + let search = nums[left..right + 1].binary_search(&target); + if search.is_err() { + return -1; + } + let search = search.unwrap() + left; + let mut right_most = Self::search_right_most(nums, target, search + 1, right); + if right_most == -1 { + search as i32 + } else { + right_most + } } } diff --git a/src/solution/s0039_combination_sum.rs b/src/solution/s0039_combination_sum.rs index b31e397e..57ffedcb 100644 --- a/src/solution/s0039_combination_sum.rs +++ b/src/solution/s0039_combination_sum.rs @@ -38,9 +38,9 @@ */ pub struct Solution {} -// problem: https://leetcode.com/problems/combination-sum/ -// discuss: https://leetcode.com/problems/combination-sum/discuss/?currentPage=1&orderBy=most_votes&query= - +// problem: https://leetcode.com/problems/combination-sum/ +// discuss: https://leetcode.com/problems/combination-sum/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here impl Solution { @@ -74,6 +74,33 @@ impl Solution { } } } + + pub fn combination_sum_1(candidates: Vec, target: i32) -> Vec> { + let mut ret = vec![]; + Self::helper(&candidates, target, &mut vec![], 0, &mut ret); + ret + } + + fn helper( + candidates: &Vec, + target: i32, + curr: &mut Vec, + start_index: usize, + ret: &mut Vec>, + ) { + if target == 0 { + ret.push(curr.clone()); + return; + } + if target < 0 { + return; + } + for i in start_index..candidates.len() { + curr.push(candidates[i]); + Self::helper(candidates, target - candidates[i], curr, i, ret); + curr.pop(); + } + } } // submission codes end diff --git a/src/solution/s0043_multiply_strings.rs b/src/solution/s0043_multiply_strings.rs index 8c487b8e..d277aaca 100644 --- a/src/solution/s0043_multiply_strings.rs +++ b/src/solution/s0043_multiply_strings.rs @@ -33,26 +33,69 @@ pub struct Solution {} // submission codes start here -// TODO -use std::char::from_digit; -use std::collections::VecDeque; +// TODO: optimize impl Solution { pub fn multiply(num1: String, num2: String) -> String { - let mut num1: Vec = num1.chars().map(|ch| ch.to_digit(10).unwrap()).collect(); - let mut num2: Vec = num2.chars().map(|ch| ch.to_digit(10).unwrap()).collect(); - let mut buffer = VecDeque::with_capacity(num2.len() + 1); - let mut res: Vec = Vec::new(); - let mut carry = 0_u32; - num1.reverse(); - num2.reverse(); - for (i, multiplier) in num1.into_iter().enumerate() { - buffer - .pop_back() - .and_then(|digit| Some(res.push(from_digit(digit, 10).unwrap()))); - for &multiplicand in num2.iter() {} + if num1.starts_with("0") || num2.starts_with("0") { + return "0".to_string(); } - res.reverse(); - res.into_iter().collect() + let num1: Vec = num1.chars().collect(); + let num2: Vec = num2.chars().collect(); + let mut ret = vec![]; + for i in 0..num1.len() { + if num1[i] == '0' { + continue; + } + for j in 0..num2.len() { + if num2[j] == '0' { + continue; + } + let zeros = num1.len() - 1 - i + num2.len() - 1 - j; + let mut curr = Self::multiply_char_char(num1[i], num2[j]); + Self::pad_zeros(&mut curr, zeros); + ret = Self::add_string(ret, curr.chars().collect()); + } + } + ret.iter().collect() + } + + fn multiply_char_char(c1: char, c2: char) -> String { + (c1.to_digit(10).unwrap() * c2.to_digit(10).unwrap()).to_string() + } + + fn add_string(num1: Vec, num2: Vec) -> Vec { + let mut ret = vec!['0'; num1.len().max(num2.len())]; + let mut index1 = num1.len() as i32 - 1; + let mut index2 = num2.len() as i32 - 1; + let mut carrier = 0; + while index1 >= 0 || index2 >= 0 { + let mut v1 = 0; + if index1 >= 0 { + v1 = num1[index1 as usize].to_digit(10).unwrap(); + } + let mut v2 = 0; + if index2 >= 0 { + v2 = num2[index2 as usize].to_digit(10).unwrap(); + } + let sum = v1 + v2 + carrier; + let curr = sum % 10; + carrier = sum / 10; + ret[index1.max(index2) as usize] = std::char::from_digit(curr, 10).unwrap(); + if index1 >= 0 { + index1 -= 1; + } + if index2 >= 0 { + index2 -= 1; + } + } + if carrier > 0 { + ret.insert(0, std::char::from_digit(carrier, 10).unwrap()); + } + ret + } + + fn pad_zeros(s: &mut String, zeros: usize) { + (0..zeros).map(|_| s.push('0')).count(); } } diff --git a/src/solution/s0048_rotate_image.rs b/src/solution/s0048_rotate_image.rs index 6f6fdffa..b13efd49 100644 --- a/src/solution/s0048_rotate_image.rs +++ b/src/solution/s0048_rotate_image.rs @@ -50,9 +50,9 @@ */ pub struct Solution {} -// problem: https://leetcode.com/problems/rotate-image/ -// discuss: https://leetcode.com/problems/rotate-image/discuss/?currentPage=1&orderBy=most_votes&query= - +// problem: https://leetcode.com/problems/rotate-image/ +// discuss: https://leetcode.com/problems/rotate-image/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here // x,y -> y,n-x 2-dimension vector rotate -90 degree: @@ -92,6 +92,26 @@ impl Solution { } } } + + pub fn rotate_1(matrix: &mut Vec>) { + let n = matrix.len(); + // top-down flip + for i in 0..n / 2 { + for j in 0..n { + let tmp = matrix[i][j]; + matrix[i][j] = matrix[n - 1 - i][j]; + matrix[n - 1 - i][j] = tmp; + } + } + // diagonal + for i in 0..n { + for j in 0..i { + let tmp = matrix[i][j]; + matrix[i][j] = matrix[j][i]; + matrix[j][i] = tmp; + } + } + } } // submission codes end diff --git a/src/solution/s0050_powx_n.rs b/src/solution/s0050_powx_n.rs index 3e2e9b3e..ef99c535 100644 --- a/src/solution/s0050_powx_n.rs +++ b/src/solution/s0050_powx_n.rs @@ -35,15 +35,35 @@ */ pub struct Solution {} -// problem: https://leetcode.com/problems/powx-n/ -// discuss: https://leetcode.com/problems/powx-n/discuss/?currentPage=1&orderBy=most_votes&query= - +// problem: https://leetcode.com/problems/powx-n/ +// discuss: https://leetcode.com/problems/powx-n/discuss/?currentPage=1&orderBy=most_votes&query= + // submission codes start here -impl Solution { - pub fn my_pow(x: f64, n: i32) -> f64 { - x.powi(n) +pub fn my_pow(x: f64, n: i32) -> f64 { + if x == 0_f64 || x == 1_f64 { + return x; + } + if n == 0 { + return 1_f64; + } + if n == 1 { + return x; + } + let mut tmp = 1_f64; + let mut x = x; + let mut n = n; + if n == std::i32::MIN { + tmp = 1_f64 / x; + n += 1; + } + if n < 0 { + x = 1_f64 / x; + n = -n; } + let half = Self::my_pow(x, n / 2); + let extra = if n % 2 == 0 { 1_f64 } else { x }; + half * half * extra * tmp } // submission codes end From a62140562f985a8f23eb1de1930a16deb6046e8b Mon Sep 17 00:00:00 2001 From: songyzh Date: Sat, 29 Feb 2020 21:43:04 +0800 Subject: [PATCH 29/31] fix 50 --- src/solution/s0050_powx_n.rs | 48 +++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/solution/s0050_powx_n.rs b/src/solution/s0050_powx_n.rs index ef99c535..fd8d3add 100644 --- a/src/solution/s0050_powx_n.rs +++ b/src/solution/s0050_powx_n.rs @@ -40,30 +40,32 @@ pub struct Solution {} // submission codes start here -pub fn my_pow(x: f64, n: i32) -> f64 { - if x == 0_f64 || x == 1_f64 { - return x; +impl Solution { + pub fn my_pow(x: f64, n: i32) -> f64 { + if x == 0_f64 || x == 1_f64 { + return x; + } + if n == 0 { + return 1_f64; + } + if n == 1 { + return x; + } + let mut tmp = 1_f64; + let mut x = x; + let mut n = n; + if n == std::i32::MIN { + tmp = 1_f64 / x; + n += 1; + } + if n < 0 { + x = 1_f64 / x; + n = -n; + } + let half = Self::my_pow(x, n / 2); + let extra = if n % 2 == 0 { 1_f64 } else { x }; + half * half * extra * tmp } - if n == 0 { - return 1_f64; - } - if n == 1 { - return x; - } - let mut tmp = 1_f64; - let mut x = x; - let mut n = n; - if n == std::i32::MIN { - tmp = 1_f64 / x; - n += 1; - } - if n < 0 { - x = 1_f64 / x; - n = -n; - } - let half = Self::my_pow(x, n / 2); - let extra = if n % 2 == 0 { 1_f64 } else { x }; - half * half * extra * tmp } // submission codes end From c078c525666b9b423601aec49007558c8e0a72b2 Mon Sep 17 00:00:00 2001 From: songyzh Date: Sat, 29 Feb 2020 21:46:25 +0800 Subject: [PATCH 30/31] optimize 289 --- src/solution/s0289_game_of_life.rs | 69 ++++++++++++++---------------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/src/solution/s0289_game_of_life.rs b/src/solution/s0289_game_of_life.rs index 53d34623..4956df5c 100644 --- a/src/solution/s0289_game_of_life.rs +++ b/src/solution/s0289_game_of_life.rs @@ -51,52 +51,47 @@ pub struct Solution {} // in-place: 1: live->live, 0: die->die, 2: die->live, 3: live->die impl Solution { pub fn game_of_life(board: &mut Vec>) { - let (height, width) = (board.len(), board[0].len()); - let neighbors = vec![ - (-1, -1), - (-1, 0), - (-1, 1), - (0, -1), - (0, 1), - (1, -1), - (1, 0), - (1, 1), - ]; - for i in 0..height { - for j in 0..width { - let mut live = 0; - for offset in neighbors.iter() { - if (offset.0 < 0 && i == 0) - || (offset.0 > 0 && i == height - 1) - || (offset.1 < 0 && j == 0) - || (offset.1 > 0 && j == width - 1) - { - continue; + let mut to_live = vec![]; + let mut to_dead = vec![]; + for i in 0..board.len() { + for j in 0..board[0].len() { + let surrounding_lives = Self::helper(board, i, j); + if board[i][j] == 1 { + if surrounding_lives < 2 || surrounding_lives > 3 { + to_dead.push((i, j)); } - let v = board[(i as i32 + offset.0) as usize][(j as i32 + offset.1) as usize]; - if v == 1 || v == 3 { - live += 1; + } else { + if surrounding_lives == 3 { + to_live.push((i, j)); } } - if board[i][j] == 1 && (live < 2 || live > 3) { - // go die - board[i][j] = 3; - } else if board[i][j] == 0 && live == 3 { - // go live - board[i][j] = 2; - } } } + for (i, j) in to_live { + board[i][j] = 1; + } + for (i, j) in to_dead { + board[i][j] = 0; + } + } - for i in 0..height { - for j in 0..width { - if board[i][j] == 2 { - board[i][j] = 1; - } else if board[i][j] == 3 { - board[i][j] = 0; + fn helper(board: &Vec>, i: usize, j: usize) -> i32 { + // count surrounding lives + let i = i as i32; + let j = j as i32; + let mut ret = 0; + for k in i - 1..i + 2 { + if k < 0 || k >= board.len() as i32 { + continue; + } + for l in j - 1..j + 2 { + if l < 0 || l >= board[0].len() as i32 { + continue; } + ret += board[k as usize][l as usize]; } } + ret - board[i as usize][j as usize] } } From a6047e8f04aa89838dc07b72b0838a90ff14904d Mon Sep 17 00:00:00 2001 From: songyzh Date: Sun, 8 Mar 2020 22:29:38 +0800 Subject: [PATCH 31/31] add key indexed counting sort --- src/algorithm/heap_sort.rs | 4 +-- src/algorithm/key_indexed_counting.rs | 37 +++++++++++++++++++++++++++ src/algorithm/mod.rs | 1 + src/algorithm/quick_sort.rs | 4 +-- src/util/vec.rs | 6 ----- 5 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 src/algorithm/key_indexed_counting.rs diff --git a/src/algorithm/heap_sort.rs b/src/algorithm/heap_sort.rs index 08951651..b0d2492e 100644 --- a/src/algorithm/heap_sort.rs +++ b/src/algorithm/heap_sort.rs @@ -7,7 +7,7 @@ fn heap_sort(v: &mut Vec) { } while end > 0 { - swap(v, 0, end); + v.swap(0, end); end -= 1; sink(0, v, end); } @@ -36,7 +36,7 @@ fn sink(i: usize, v: &mut Vec, end: usize) { bigger = right; } if bigger != i { - swap(v, i, bigger); + v.swap(i, bigger); sink(bigger, v, end); } } diff --git a/src/algorithm/key_indexed_counting.rs b/src/algorithm/key_indexed_counting.rs new file mode 100644 index 00000000..e839efb4 --- /dev/null +++ b/src/algorithm/key_indexed_counting.rs @@ -0,0 +1,37 @@ +use crate::util::vec::*; + +fn key_indexed_counting_sort(v: Vec) -> Vec { + let max = v.iter().max().unwrap(); + let mut count = vec![0; max + 2]; + // count + for t in &v { + count[t + 1] += 1; + } + // transform + for i in 1..count.len() { + count[i] += count[i - 1]; + } + // distribute + let mut aux = vec![0; v.len()]; + // reverse to keep the sort stable + for i in 0..v.len() { + aux[count[v[i]]] = v[i]; + count[v[i]] += 1; + } + return aux; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_insertion_sort() { + let mut shuffled = get_shuffled_vec().into_iter().map(|x| x as usize).collect(); + let sorted: Vec = key_indexed_counting_sort(shuffled) + .into_iter() + .map(|x| x as i32) + .collect(); + assert_eq!(get_sorted_vec(), sorted); + } +} diff --git a/src/algorithm/mod.rs b/src/algorithm/mod.rs index d89807b8..3511dcd8 100644 --- a/src/algorithm/mod.rs +++ b/src/algorithm/mod.rs @@ -1,3 +1,4 @@ mod heap_sort; mod insertion_sort; +mod key_indexed_counting; mod quick_sort; diff --git a/src/algorithm/quick_sort.rs b/src/algorithm/quick_sort.rs index 958547c2..3502adbc 100644 --- a/src/algorithm/quick_sort.rs +++ b/src/algorithm/quick_sort.rs @@ -16,11 +16,11 @@ fn partition(v: &mut Vec, left: i32, right: i32) -> i32 { let i = i as usize; if v[i] <= value { pivot += 1; - swap(v, i, pivot as usize); + v.swap(i, pivot as usize); } } pivot += 1; - swap(v, pivot as usize, right as usize); + v.swap(pivot as usize, right as usize); pivot } diff --git a/src/util/vec.rs b/src/util/vec.rs index 28149b4f..980d3414 100644 --- a/src/util/vec.rs +++ b/src/util/vec.rs @@ -1,12 +1,6 @@ use rand::seq::SliceRandom; use rand::{thread_rng, Rng}; -pub fn swap(v: &mut Vec, i: usize, j: usize) { - let tmp = v[i]; - v[i] = v[j]; - v[j] = tmp; -} - pub fn get_sorted_vec() -> Vec { (0..10).collect() }