├── .gitignore ├── Cargo.toml ├── src ├── lc_009_jump_game.rs ├── lc_010_jump_game_2.rs ├── lc_001_two_sum.rs ├── lc_004_best_time_to_buy_and_sell_stock.rs ├── lc_013_evaluate_reverse_polish_notation.rs ├── lib.rs ├── lc_005_maximum_subarray.rs ├── lc_002_count_good_meals.rs ├── lc_003_valid_parentheses.rs ├── lc_007_01_matrix.rs ├── lc_011_longest_substring_without_repeating_characters.rs ├── lc_008_k_closest_points_to_origin.rs ├── lc_006_overlapping_intervals.rs ├── lc_012_product_of_array_except_self.rs └── main.rs ├── README.md └── update_readme.py /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lc" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /src/lc_009_jump_game.rs: -------------------------------------------------------------------------------- 1 | // Title: Jump Game 2 | // Link: https://leetcode.com/problems/jump-game/ 3 | 4 | pub fn can_jump(nums: Vec) -> bool { 5 | let mut curr_idx = nums.len() - 1; 6 | 7 | for right_idx in (0..nums.len()).rev() { 8 | if right_idx as i32 + nums[right_idx] >= curr_idx as i32 { 9 | curr_idx = right_idx; 10 | } 11 | } 12 | 13 | curr_idx == 0 14 | } 15 | 16 | 17 | #[cfg(test)] 18 | mod test { 19 | use super::*; 20 | 21 | #[test] 22 | fn ex1_jump_game() { 23 | let inp: Vec = vec![2,3,1,1,4]; 24 | assert!(can_jump(inp)); 25 | } 26 | 27 | #[test] 28 | fn ex2_jump_game() { 29 | let inp: Vec = vec![3,2,1,0,4]; 30 | assert!(!can_jump(inp)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/lc_010_jump_game_2.rs: -------------------------------------------------------------------------------- 1 | // Title: Jump Game II 2 | // Link: https://leetcode.com/problems/jump-game-ii/ 3 | 4 | use std::cmp; 5 | 6 | pub fn jump(nums: Vec) -> i32 { 7 | let mut cur_reach: i32 = 0; 8 | let mut cur_max: i32 = 0; 9 | let mut jumps_count: i32 = 0; 10 | 11 | for (idx, val) in nums.iter().enumerate().take(nums.len() - 1) { 12 | cur_max = cmp::max(cur_max, idx as i32 + val); 13 | if idx as i32 == cur_reach { 14 | jumps_count += 1; 15 | cur_reach = cur_max; 16 | } 17 | } 18 | 19 | jumps_count 20 | } 21 | 22 | #[cfg(test)] 23 | mod test { 24 | use super::*; 25 | 26 | #[test] 27 | fn ex1_jump_game_2() { 28 | assert_eq!(jump(vec![2, 3, 1, 1, 4]), 2); 29 | } 30 | 31 | #[test] 32 | fn ex2_jump_game_2() { 33 | assert_eq!(jump(vec![2, 3, 0, 1, 4]), 2); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/lc_001_two_sum.rs: -------------------------------------------------------------------------------- 1 | // Title: Two Sum 2 | // Link: https://leetcode.com/problems/two-sum/ 3 | 4 | use std::collections::HashMap; 5 | 6 | pub fn two_sum(nums: Vec, target: i32) -> Vec { 7 | let mut map = HashMap::::new(); 8 | 9 | for i in 0..(nums.len()) { 10 | if map.contains_key(&(target - nums[i])) { 11 | return vec![i as i32, map[&(target - nums[i])]]; 12 | } else { 13 | map.insert(nums[i], i as i32); 14 | }; 15 | } 16 | vec![] 17 | } 18 | 19 | #[cfg(test)] 20 | mod test { 21 | use super::*; 22 | 23 | #[test] 24 | fn ex1() { 25 | assert_eq!(two_sum(vec![2, 7, 11, 15], 9), vec![1, 0]) 26 | } 27 | 28 | #[test] 29 | fn ex2() { 30 | assert_eq!(two_sum(vec![3, 2, 4], 6), vec![2, 1]) 31 | } 32 | 33 | #[test] 34 | fn ex3() { 35 | assert_eq!(two_sum(vec![3, 3], 6), vec![1, 0]); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/lc_004_best_time_to_buy_and_sell_stock.rs: -------------------------------------------------------------------------------- 1 | // Title: Best Time to Buy and Sell Stock 2 | // Link: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ 3 | 4 | // it's a maximum difference between 2 elements problem 5 | // with a condition that the 2 elements should be: a..b and considering b..a is not allowed 6 | use std::cmp; 7 | 8 | pub fn max_profit(prices: Vec) -> i32 { 9 | let mut max_diff = 0; 10 | let mut min_price = i32::MAX; 11 | 12 | for price in prices.iter() { 13 | min_price = cmp::min(min_price, *price); 14 | max_diff = cmp::max(*price - min_price, max_diff); 15 | } 16 | 17 | max_diff 18 | } 19 | 20 | #[cfg(test)] 21 | mod test { 22 | use super::*; 23 | 24 | #[test] 25 | fn ex1() { 26 | assert_eq!(max_profit([7, 6, 4, 3, 1].to_vec()), 0); 27 | } 28 | 29 | #[test] 30 | fn ex2() { 31 | assert_eq!(max_profit([7, 1, 5, 3, 6, 4].to_vec()), 5); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/lc_013_evaluate_reverse_polish_notation.rs: -------------------------------------------------------------------------------- 1 | pub fn eval_rpn(tokens: Vec) -> i32 { 2 | let stack: Vec = Vec::new(); 3 | for token in tokens.iter() { 4 | if 5 | } 6 | } 7 | 8 | #[cfg(test)] 9 | mod test { 10 | use super::*; 11 | 12 | #[test] 13 | fn ex1_evaluate_reverse_polish_notation() { 14 | let inp: Vec = vec!["4".into(), "13".into(), "5".into(), "/".into(), "+".into()]; 15 | assert_eq!(eval_rpn(inp), 6); 16 | } 17 | 18 | #[test] 19 | fn ex2_evaluate_reverse_polish_notation() { 20 | assert_eq!( 21 | eval_rpn(vec![ 22 | "2".into(), 23 | "1".into(), 24 | "+".into(), 25 | "3".into(), 26 | "*".into() 27 | ]), 28 | 9 29 | ); 30 | } 31 | 32 | #[test] 33 | fn ex3_evaluate_reverse_polish_notation() { 34 | assert_eq!(eval_rpn(vec!["3".into(), "4".into(), "/".into()]), 0); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod lc_001_two_sum; 2 | pub use lc_001_two_sum::*; 3 | 4 | pub mod lc_002_count_good_meals; 5 | pub use lc_002_count_good_meals::*; 6 | 7 | pub mod lc_003_valid_parentheses; 8 | pub use lc_003_valid_parentheses::*; 9 | 10 | pub mod lc_004_best_time_to_buy_and_sell_stock; 11 | pub use lc_004_best_time_to_buy_and_sell_stock::*; 12 | 13 | pub mod lc_005_maximum_subarray; 14 | pub use lc_005_maximum_subarray::*; 15 | 16 | pub mod lc_006_overlapping_intervals; 17 | pub use lc_006_overlapping_intervals::*; 18 | 19 | pub mod lc_007_01_matrix; 20 | pub use lc_007_01_matrix::*; 21 | 22 | pub mod lc_008_k_closest_points_to_origin; 23 | pub use lc_008_k_closest_points_to_origin::*; 24 | 25 | pub mod lc_009_jump_game; 26 | pub use lc_009_jump_game::*; 27 | 28 | pub mod lc_010_jump_game_2; 29 | pub use lc_010_jump_game_2::*; 30 | 31 | pub mod lc_011_longest_substring_without_repeating_characters; 32 | pub use lc_011_longest_substring_without_repeating_characters::*; 33 | 34 | pub mod lc_012_product_of_array_except_self; 35 | pub use lc_012_product_of_array_except_self::*; 36 | -------------------------------------------------------------------------------- /src/lc_005_maximum_subarray.rs: -------------------------------------------------------------------------------- 1 | // Title: Maximum Subarray 2 | // Link: https://leetcode.com/problems/maximum-subarray/ 3 | 4 | use std::cmp; 5 | 6 | pub fn max_sub_array(nums: Vec) -> i32 { 7 | let mut max_sum: i32 = i32::MIN; 8 | let mut left: i32 = 0; 9 | let mut right: i32 = 0; 10 | let mut sum = 0; 11 | 12 | while right < nums.len() as i32 { 13 | if left >= nums.len() as i32 { 14 | break; 15 | } 16 | 17 | sum += nums[right as usize]; 18 | 19 | max_sum = cmp::max(max_sum, sum); 20 | if sum < 0 { 21 | if left == right { 22 | right += 1; 23 | sum = 0; 24 | } else { 25 | sum -= nums[left as usize]; 26 | } 27 | left += 1; 28 | } else { 29 | right += 1; 30 | } 31 | } 32 | 33 | max_sum 34 | } 35 | 36 | #[cfg(test)] 37 | mod test { 38 | use super::*; 39 | 40 | #[test] 41 | fn ex1() { 42 | assert_eq!(max_sub_array([-2, 1, -3, 4, -1, 2, 1, -5, 4].to_vec()), 6); 43 | } 44 | 45 | #[test] 46 | fn ex2() { 47 | assert_eq!(max_sub_array([1].to_vec()), 1); 48 | } 49 | 50 | #[test] 51 | fn ex3() { 52 | assert_eq!(max_sub_array([5, 4, -1, 7, 8].to_vec()), 23); 53 | } 54 | 55 | #[test] 56 | fn ex4() { 57 | assert_eq!(max_sub_array([-2, -1, -3, -4].to_vec()), -1); 58 | } 59 | 60 | #[test] 61 | fn ex5() { 62 | assert_eq!(max_sub_array([8, -19, 5, -4, 20].to_vec()), 21); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/lc_002_count_good_meals.rs: -------------------------------------------------------------------------------- 1 | // Title: Count Good Meals 2 | // Link: https://leetcode.com/problems/count-good-meals 3 | 4 | // Status: TLE 5 | use std::collections::HashMap; 6 | 7 | pub fn is_factor_of( 8 | mut sum: i32, 9 | _idx1: i32, 10 | _idx2: i32, 11 | record_map: &mut HashMap, 12 | factor_of: i32, 13 | ) -> bool { 14 | let mut visited = vec![]; 15 | if record_map.contains_key(&sum) { 16 | record_map[&sum] 17 | } else { 18 | while sum != 0 { 19 | if sum != 1 && sum % factor_of != 0 { 20 | return false; 21 | } else { 22 | visited.push(sum); 23 | sum /= factor_of; 24 | if record_map.contains_key(&sum) { 25 | break; 26 | } else { 27 | continue; 28 | } 29 | } 30 | } 31 | for val in visited.iter() { 32 | record_map.insert(*val, true); 33 | } 34 | true 35 | } 36 | } 37 | 38 | pub fn count_pairs(deliciousness: Vec) -> i32 { 39 | let mut record_map = HashMap::::new(); 40 | let mut count: i32 = 0; 41 | for i in 0..deliciousness.len() { 42 | for j in i + 1..deliciousness.len() { 43 | let sum = deliciousness[i] + deliciousness[j]; 44 | if sum == 0 { 45 | continue; 46 | } else if is_factor_of(sum, i as i32, j as i32, &mut record_map, 2) { 47 | count += 1; 48 | } 49 | } 50 | } 51 | count 52 | } 53 | 54 | #[cfg(test)] 55 | mod test { 56 | use super::*; 57 | 58 | #[test] 59 | fn ex1() { 60 | assert_eq!(count_pairs(vec![1, 3, 5, 7, 9]), 4); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/lc_003_valid_parentheses.rs: -------------------------------------------------------------------------------- 1 | // Title: Valid Parentheses 2 | // Link: https://leetcode.com/problems/valid-parentheses/ 3 | 4 | pub fn is_valid(inp: String) -> bool { 5 | let mut paren_stack: Vec = vec![]; 6 | let open_brackets: Vec = vec!['{', '[', '(']; 7 | let close_brackets: Vec = vec!['}', ']', ')']; 8 | 9 | // Enumerating just in case I need index (_idx) later... 10 | for (_idx, inp_char) in inp.chars().enumerate() { 11 | if open_brackets.contains(&inp_char) { 12 | paren_stack.push(inp_char); 13 | } else if close_brackets.contains(&inp_char) { 14 | if paren_stack.is_empty() { 15 | return false; 16 | } else { 17 | let output = match paren_stack[paren_stack.len() - 1] { 18 | '{' => inp_char == '}', 19 | '[' => inp_char == ']', 20 | '(' => inp_char == ')', 21 | _ => false, 22 | }; 23 | 24 | if !output { 25 | return false; 26 | } 27 | 28 | paren_stack.pop(); 29 | } 30 | } 31 | } 32 | paren_stack.is_empty() 33 | } 34 | 35 | #[cfg(test)] 36 | mod test { 37 | use super::*; 38 | 39 | #[test] 40 | fn ex1() { 41 | assert!(is_valid("{}{}{}()[]".to_string())); 42 | } 43 | 44 | #[test] 45 | fn ex2() { 46 | assert!(is_valid("()[]{}".to_string())); 47 | } 48 | 49 | #[test] 50 | fn ex3() { 51 | assert!(!is_valid("({}[)".to_string())); 52 | } 53 | 54 | #[test] 55 | fn ex4() { 56 | assert!(!is_valid("(".to_string())); 57 | } 58 | 59 | #[test] 60 | fn ex5() { 61 | assert!(!is_valid("((}}".to_string())); 62 | } 63 | 64 | #[test] 65 | fn ex6() { 66 | assert!(!is_valid("}(){}".to_string())) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/lc_007_01_matrix.rs: -------------------------------------------------------------------------------- 1 | // Title: 01 Matrix 2 | // Link: https://leetcode.com/problems/01-matrix/ 3 | 4 | // Couldn't do it myself correctly 5 | // Please refer to: https://leetcode.com/problems/01-matrix/discuss/1370412/rust-bfs-solution 6 | // Credits to him^ 7 | 8 | use std::collections::VecDeque; 9 | 10 | pub fn update_matrix(mat: &Vec>) -> Vec> { 11 | let (r, c) = (mat.len(), mat[0].len()); 12 | // initializing 2D vector with all i32::MAX values 13 | // size: r x c (height x width) 14 | let mut answer = vec![vec![i32::MAX; c]; r]; 15 | let mut vd = VecDeque::new(); 16 | 17 | for (i, row) in mat.iter().enumerate() { 18 | for (j, col) in row.iter().enumerate() { 19 | if * col == 0 { 20 | answer[i][j] = 0; 21 | vd.push_back((i, j)); 22 | } 23 | } 24 | } 25 | 26 | while let Some((i, j)) = vd.pop_front() { 27 | for d in [0, 1, 0, !0, 0].windows(2) { 28 | let di = i.wrapping_add(d[0]); 29 | let dj = j.wrapping_add(d[1]); 30 | if di < r && dj < c && answer[di][dj] > answer[i][j] { 31 | answer[di][dj] = answer[i][j] + 1; 32 | vd.push_back((di, dj)); 33 | } 34 | } 35 | } 36 | 37 | answer 38 | } 39 | 40 | #[cfg(test)] 41 | mod test { 42 | use super::*; 43 | 44 | #[test] 45 | fn ex1() { 46 | let inp: Vec> = 47 | [[0, 0, 0].to_vec(), [0, 1, 0].to_vec(), [1, 1, 1].to_vec()].to_vec(); 48 | let out: Vec> = 49 | [[0, 0, 0].to_vec(), [0, 1, 0].to_vec(), [1, 2, 1].to_vec()].to_vec(); 50 | assert_eq!(update_matrix(&inp), out); 51 | } 52 | 53 | #[test] 54 | fn ex2() { 55 | let inp = [[0,0,0].to_vec(),[0,1,0].to_vec(),[0,0,0].to_vec()].to_vec(); 56 | let out = [[0,0,0],[0,1,0],[0,0,0]]; 57 | assert_eq!(update_matrix(&inp), out); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/lc_011_longest_substring_without_repeating_characters.rs: -------------------------------------------------------------------------------- 1 | // Title: Longest Substring without Repeating Characters 2 | // Link: https://leetcode.com/problems/longest-substring-without-repeating-characters/ 3 | 4 | use std::cmp; 5 | use std::collections::HashMap; 6 | 7 | pub fn length_of_longest_substring(s: String) -> i32 { 8 | let s_bytes = s.as_bytes(); 9 | 10 | let mut cur_window_map: HashMap = HashMap::new(); 11 | let mut left: i32 = 0; 12 | let mut right: i32 = 0; 13 | 14 | let mut result: i32 = 0; 15 | 16 | while (left as usize) < s.len() && (right as usize) < s.len() { 17 | let char_string: &u8 = &s_bytes[right as usize]; 18 | 19 | if cur_window_map.contains_key(char_string) { 20 | let new_left = cur_window_map[char_string] + 1; 21 | for range_idx in left..new_left { 22 | let to_remove = &s_bytes[range_idx as usize]; 23 | if cur_window_map.contains_key(to_remove) { 24 | cur_window_map.remove_entry(to_remove); 25 | } 26 | } 27 | left = new_left; 28 | continue; 29 | } 30 | 31 | cur_window_map.insert(*char_string, right); 32 | 33 | result = cmp::max(right - left + 1, result); 34 | right += 1; 35 | } 36 | 37 | result 38 | } 39 | 40 | #[cfg(test)] 41 | mod test { 42 | use super::*; 43 | 44 | #[test] 45 | fn ex1_length_of_longest_substring_wo_repeating_chars() { 46 | assert_eq!(length_of_longest_substring("abcabcbb".to_string()), 3); 47 | } 48 | 49 | #[test] 50 | fn ex2_length_of_longest_substring_wo_repeating_chars() { 51 | assert_eq!(length_of_longest_substring("bbbbb".to_string()), 1); 52 | } 53 | 54 | #[test] 55 | fn ex3_length_of_longest_substring_wo_repeating_chars() { 56 | assert_eq!(length_of_longest_substring("abccbdefgh".to_string()), 7); 57 | } 58 | 59 | #[test] 60 | fn ex4_length_of_longest_substring_wo_repeating_chars() { 61 | assert_eq!(length_of_longest_substring("dvdf".to_string()), 3); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-leetcode 2 | 3 | **Solving Leetcode problems in Rust** 4 | 5 | 1. [Two Sum](https://leetcode.com/problems/two-sum/): [`lc_001_two_sum`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_001_two_sum.rs) 6 | 2. [Count Good Meals](https://leetcode.com/problems/count-good-meals): [`lc_002_count_good_meals`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_002_count_good_meals.rs) 7 | 3. [Valid Parentheses](https://leetcode.com/problems/valid-parentheses/): [`lc_003_valid_parentheses`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_003_valid_parentheses.rs) 8 | 4. [Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/): [`lc_004_best_time_to_buy_and_sell_stock`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_004_best_time_to_buy_and_sell_stock.rs) 9 | 5. [Maximum Subarray](https://leetcode.com/problems/maximum-subarray/): [`lc_005_maximum_subarray`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_005_maximum_subarray.rs) 10 | 6. [Insert Interval](https://leetcode.com/problems/insert-interval/): [`lc_006_overlapping_intervals`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_006_overlapping_intervals.rs) 11 | 7. [01 Matrix](https://leetcode.com/problems/01-matrix/): [`lc_007_01_matrix`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_007_01_matrix.rs) 12 | 8. [K Closest Points to Origin](https://leetcode.com/problems/k-closest-points-to-origin/): [`lc_008_k_closest_points_to_origin`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_008_k_closest_points_to_origin.rs) 13 | 9. [Jump Game](https://leetcode.com/problems/jump-game/): [`lc_009_jump_game`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_009_jump_game.rs) 14 | 10. [Jump Game II](https://leetcode.com/problems/jump-game-ii/): [`lc_010_jump_game_2`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_010_jump_game_2.rs) 15 | 11. [Longest Substring without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/): [`lc_011_longest_substring_without_repeating_characters`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_011_longest_substring_without_repeating_characters.rs) 16 | 12. [Product of Array except Self](https://leetcode.com/problems/product-of-array-except-self): [`lc_012_product_of_array_except_self`](https://github.com/krshrimali/rust-leetcode/blob/main/src/lc_012_product_of_array_except_self.rs) 17 | 18 | Full disclosure: I was inspired by [UncleScientist](https://www.youtube.com/c/UncleScientist) to do it this way, specially the testing. 19 | 20 | This was autogenerated from my Rust script, check out: [src/main.rs](https://github.com/krshrimali/rust-leetcode/blob/main/src/main.rs). -------------------------------------------------------------------------------- /update_readme.py: -------------------------------------------------------------------------------- 1 | # Need to convert this to Rust soon :) 2 | import os, sys 3 | 4 | PREFIX = "https://github.com/krshrimali/rust-leetcode/blob/main/" 5 | README_PREFIX = """# rust-leetcode 6 | 7 | Solving Leetcode problems in Rust 8 | 9 | """ 10 | 11 | README_SUFFIX = """ 12 | Full disclosure: I was inspired by [UncleScientist](https://www.youtube.com/c/UncleScientist) to do it this way, specially the testing. 13 | """ 14 | 15 | 16 | def make_href(title, link): 17 | return "[" + title + "]" + "(" + link + ")" 18 | 19 | 20 | def update_readme(debug: bool): 21 | with open("README.md", "w+") as readme_file: 22 | readme_file.write(README_PREFIX) 23 | count = 1 24 | with open("src/lib.rs") as lib_file: 25 | lines = lib_file.readlines() 26 | for line in lines: 27 | if line.startswith("pub mod"): 28 | line = line.strip("pub mod ").strip("\n").strip(";") 29 | filename = "src/" + line + ".rs" 30 | if debug: 31 | print("File: ", filename) 32 | assert os.path.isfile(filename), f"{filename} doesn't exist..." 33 | with open(filename) as code_file: 34 | lines = code_file.readlines()[:2] 35 | try: 36 | title = ( 37 | lines[0].strip("//").strip("\n").split(" Title: ")[1] 38 | ) 39 | link = lines[1].strip("//").strip("\n").split(" Link: ")[1] 40 | except Exception as e: 41 | msg = "Please look at other files to see the format. // Title: and // Link: as first 2 lines." 42 | print(msg) 43 | raise e 44 | first_part = make_href(title, link) 45 | second_part = make_href(f"`{filename}`", PREFIX + filename) 46 | row = str(count) + ". " + first_part + ": " + second_part + "\n" 47 | if debug: 48 | print(f"Parsed parts: {first_part}, {second_part}") 49 | print(f"Row: {row}") 50 | readme_file.write(row) 51 | count += 1 52 | readme_file.write(README_SUFFIX) 53 | 54 | 55 | if __name__ == "__main__": 56 | import argparse 57 | 58 | parser = argparse.ArgumentParser( 59 | prog="ReadmeUpdater", 60 | description="Generates the README from src/lib.rs and src/*.rs files", 61 | ) 62 | parser.add_argument("-debug", "--debug", default=False) 63 | args = parser.parse_args() 64 | update_readme(args.debug in ["True", "true", "TRUE"]) 65 | -------------------------------------------------------------------------------- /src/lc_008_k_closest_points_to_origin.rs: -------------------------------------------------------------------------------- 1 | // Title: K Closest Points to Origin 2 | // Link: https://leetcode.com/problems/k-closest-points-to-origin/ 3 | 4 | use std::cmp::Reverse; 5 | use std::collections::BinaryHeap; 6 | 7 | pub fn k_closest_min_heap(points: Vec>, k: i32) -> Vec> { 8 | // by default, a BinaryHeap is a MaxHeap in Rust 9 | let mut heap: BinaryHeap>> = BinaryHeap::new(); 10 | for pt in points.iter() { 11 | let dist: i32 = (pt[0] * pt[0]) + (pt[1] * pt[1]); 12 | heap.push(Reverse(vec![dist, pt[0], pt[1]])); 13 | } 14 | 15 | let mut result: Vec> = Vec::new(); 16 | for _ in 0..k { 17 | let top_elem = heap.pop().unwrap(); 18 | result.push(vec![top_elem.0[1], top_elem.0[2]]); 19 | } 20 | 21 | result 22 | } 23 | 24 | pub fn k_closest_max_heap(points: Vec>, k: i32) -> Vec> { 25 | let k = k as usize; 26 | let mut heap = BinaryHeap::with_capacity(k); 27 | for pt in points.iter() { 28 | let dist: i32 = (pt[0] * pt[0]) + (pt[1] * pt[1]); 29 | heap.push((dist, vec![pt[0], pt[1]])); 30 | if heap.len() > k { 31 | heap.pop(); 32 | } 33 | } 34 | 35 | // https://leetcode.com/problems/k-closest-points-to-origin/discuss/2003312/Rust-BinaryHeap 36 | // Full credits to the guy above for this max heap function... was just trying to see how 37 | // he used .map(...).collect(), neat but maybe not too readable (but I still wanted to learn) 38 | heap.into_iter().map(|(_, coord)| coord).collect() 39 | } 40 | 41 | #[cfg(test)] 42 | mod test { 43 | use super::*; 44 | 45 | #[test] 46 | fn ex1_k_closest_points_to_origin_max_heap() { 47 | let inp: Vec> = vec![vec![1, 3], vec![-2, 2]]; 48 | let expected_out: Vec> = vec![vec![-2, 2]]; 49 | assert_eq!(k_closest_max_heap(inp, 1), expected_out); 50 | } 51 | 52 | #[test] 53 | fn ex2_k_closest_points_to_origin_max_heap() { 54 | let inp = vec![vec![3, 3], vec![5, -1], vec![-2, 4]]; 55 | let mut expected_out = vec![vec![3, 3], vec![-2, 4]]; 56 | expected_out.sort(); 57 | assert_eq!(k_closest_max_heap(inp, 2), expected_out); 58 | } 59 | 60 | #[test] 61 | fn ex1_k_closest_points_to_origin_min_heap() { 62 | let inp: Vec> = vec![vec![1, 3], vec![-2, 2]]; 63 | let expected_out: Vec> = vec![vec![-2, 2]]; 64 | assert_eq!(k_closest_min_heap(inp, 1), expected_out); 65 | } 66 | 67 | #[test] 68 | fn ex2_k_closest_points_to_origin_min_heap() { 69 | let inp = vec![vec![3, 3], vec![5, -1], vec![-2, 4]]; 70 | let expected_out = vec![vec![3, 3], vec![-2, 4]]; 71 | assert_eq!(k_closest_min_heap(inp, 2), expected_out); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/lc_006_overlapping_intervals.rs: -------------------------------------------------------------------------------- 1 | // Title: Insert Interval 2 | // Link: https://leetcode.com/problems/insert-interval/ 3 | 4 | pub fn insert(intervals: Vec>, new_interval: Vec) -> Vec> { 5 | let new_start = new_interval[0]; 6 | let new_end = new_interval[1]; 7 | 8 | let mut start_idx: i32 = -1; 9 | let mut end_idx: i32 = -1; 10 | for (idx, interval) in intervals.iter().enumerate() { 11 | if new_start >= interval[0] { 12 | if new_start >= interval[1] { 13 | continue; 14 | } else { 15 | start_idx = idx as i32; 16 | } 17 | 18 | if new_end >= interval[1] { 19 | continue; 20 | } else { 21 | return intervals; 22 | } 23 | } else if new_end >= interval[0] { 24 | if new_end <= interval[1] { 25 | end_idx = idx as i32; 26 | } else { 27 | continue; 28 | } 29 | } 30 | 31 | if end_idx == -1 && new_end <= interval[0] { 32 | end_idx = idx as i32 - 1; 33 | } 34 | if start_idx == -1 && new_start <= interval[0] { 35 | start_idx = idx as i32 - 1; 36 | } 37 | } 38 | 39 | let mut result: Vec> = [].to_vec(); 40 | 41 | if start_idx == -1 && end_idx == -1 { 42 | intervals 43 | } else { 44 | let mut i = 0; 45 | while i < intervals.len() { 46 | let interval: &Vec = &intervals[i]; 47 | println!("start_idx: {}, end_idx: {}", start_idx, end_idx); 48 | if i as i32 == start_idx { 49 | result.push( 50 | [ 51 | intervals[start_idx as usize][0], 52 | intervals[end_idx as usize][1], 53 | ] 54 | .to_vec(), 55 | ); 56 | while i as i32 != end_idx { 57 | i += 1; 58 | } 59 | } else { 60 | result.push(interval.to_vec()); 61 | } 62 | i += 1; 63 | } 64 | result 65 | } 66 | } 67 | 68 | #[cfg(test)] 69 | mod test { 70 | use super::*; 71 | 72 | #[test] 73 | fn ex1() { 74 | let mut inp: Vec> = [].to_vec(); 75 | inp.push([1, 3].to_vec()); 76 | inp.push([6, 9].to_vec()); 77 | assert_eq!(insert(inp, [2, 5].to_vec()), [[1, 5], [6, 9]]); 78 | } 79 | 80 | #[test] 81 | fn ex2() { 82 | let inp = [ 83 | [1, 2].to_vec(), 84 | [3, 5].to_vec(), 85 | [6, 7].to_vec(), 86 | [8, 10].to_vec(), 87 | [12, 16].to_vec(), 88 | ] 89 | .to_vec(); 90 | assert_eq!(insert(inp, [4, 8].to_vec()), [[1, 2], [3, 10], [12, 16]]); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/lc_012_product_of_array_except_self.rs: -------------------------------------------------------------------------------- 1 | // Title: Product of Array except Self 2 | // Link: https://leetcode.com/problems/product-of-array-except-self 3 | 4 | pub fn product_except_self(nums: Vec) -> Vec { 5 | if nums.is_empty() { 6 | return nums; 7 | } 8 | 9 | let mut left_mul: Vec = vec![0; nums.len()]; 10 | let mut right_mul: Vec = vec![0; nums.len()]; 11 | 12 | left_mul[0] = 1; 13 | for idx in 1..nums.len() { 14 | left_mul[idx] = left_mul[idx - 1] * nums[idx - 1]; 15 | } 16 | 17 | right_mul[nums.len() - 1] = 1; 18 | for idx in (0..nums.len() - 1).rev() { 19 | right_mul[idx] = right_mul[idx + 1] * nums[idx + 1]; 20 | } 21 | 22 | left_mul 23 | .iter() 24 | .zip(right_mul.iter()) 25 | .map(|(x, y)| x * y) 26 | .collect() 27 | } 28 | 29 | pub fn product_except_self_space_optimized(nums: Vec) -> Vec { 30 | if nums.is_empty() { 31 | return nums; 32 | } 33 | 34 | let mut ans: Vec = vec![0; nums.len()]; 35 | ans[0] = 1; 36 | ans[nums.len() - 1] = 1; 37 | 38 | for idx in 1..nums.len() { 39 | ans[idx] = ans[idx - 1] * nums[idx - 1]; 40 | } 41 | 42 | let mut prod_to_the_right: i32 = 1; 43 | for idx in (0..nums.len()).rev() { 44 | ans[idx] *= prod_to_the_right; 45 | prod_to_the_right *= nums[idx]; 46 | } 47 | 48 | ans 49 | } 50 | 51 | #[cfg(test)] 52 | mod test { 53 | use super::*; 54 | 55 | #[test] 56 | fn ex1_product_except_self() { 57 | assert_eq!(product_except_self(vec![1, -1, 2, 0]), vec![0, 0, 0, -2]); 58 | } 59 | 60 | #[test] 61 | fn ex2_product_except_self() { 62 | assert_eq!(product_except_self(vec![0, 0, 0, 0]), vec![0, 0, 0, 0]) 63 | } 64 | 65 | #[test] 66 | fn ex3_product_except_self() { 67 | assert_eq!(product_except_self(vec![]), vec![]) 68 | } 69 | 70 | #[test] 71 | fn ex4_product_except_self() { 72 | assert_eq!(product_except_self(vec![1, 4, 3, 6]), vec![72, 18, 24, 12]); 73 | } 74 | 75 | #[test] 76 | fn ex1_product_except_self_space_optimized() { 77 | assert_eq!( 78 | product_except_self_space_optimized(vec![1, -1, 2, 0]), 79 | vec![0, 0, 0, -2] 80 | ); 81 | } 82 | 83 | #[test] 84 | fn ex2_product_except_self_space_optimized() { 85 | assert_eq!( 86 | product_except_self_space_optimized(vec![0, 0, 0, 0]), 87 | vec![0, 0, 0, 0] 88 | ) 89 | } 90 | 91 | #[test] 92 | fn ex3_product_except_self_space_optimized() { 93 | assert_eq!(product_except_self_space_optimized(vec![]), vec![]) 94 | } 95 | 96 | #[test] 97 | fn ex4_product_except_self_space_optimized() { 98 | assert_eq!( 99 | product_except_self_space_optimized(vec![1, 4, 3, 6]), 100 | vec![72, 18, 24, 12] 101 | ); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::{self, BufRead, LineWriter}; 3 | use std::io::prelude::*; 4 | use std::path::Path; 5 | 6 | fn make_href(title: String, link: String) -> String { 7 | "[".to_owned() + &title + "]" + "(" + &link + ")" 8 | } 9 | 10 | fn main() -> std::io::Result<()> { 11 | let prefix: String = "https://github.com/krshrimali/rust-leetcode/blob/main/".to_string(); 12 | let readme_prefix: String = "# rust-leetcode 13 | 14 | **Solving Leetcode problems in Rust** 15 | " 16 | .to_string(); 17 | 18 | let acknowledge: String = "This was autogenerated from my Rust script, check out: [src/main.rs](https://github.com/krshrimali/rust-leetcode/blob/main/src/main.rs).".to_string(); 19 | 20 | let readme_suffix: String = " 21 | Full disclosure: I was inspired by [UncleScientist](https://www.youtube.com/c/UncleScientist) to do it this way, specially the testing.".to_string(); 22 | 23 | let file = File::create("README.md")?; 24 | let mut file = LineWriter::new(file); 25 | file.write_all(readme_prefix.as_bytes())?; 26 | file.write_all(b"\n")?; 27 | 28 | if let Ok(lines) = read_lines("src/lib.rs") { 29 | let mut count: i32 = 1; 30 | for line in lines { 31 | let ip = line.expect("couldn't find a value"); 32 | if ip.contains("pub mod ") { 33 | let mut str_ip = ip.to_string(); 34 | str_ip = str_ip 35 | .strip_prefix("pub mod ") 36 | .expect("Couldn't find prefix: pub mod ") 37 | .to_string(); 38 | str_ip = str_ip 39 | .strip_suffix(';') 40 | .expect("Couldn't find semicolon at the end: ;") 41 | .to_string(); 42 | let file_path = "src/".to_string() + &str_ip + ".rs"; 43 | if let Ok(file_lines) = read_lines(&file_path) { 44 | let mut stripped_link: String = String::from(""); 45 | let mut stripped_title: String = String::from(""); 46 | let mut code_str: String = String::from(""); 47 | for (count, file_line) in file_lines.into_iter().enumerate() { 48 | if count == 2 { 49 | break; 50 | } 51 | let comment: String = file_line.expect("no string found").to_string(); 52 | let title_line = comment.strip_prefix("// Title: "); 53 | if let Some(title) = Some(title_line) { 54 | if title.is_some() { 55 | stripped_title = title.as_ref().unwrap().to_string(); 56 | } 57 | } 58 | 59 | let link_line = comment.strip_prefix("// Link: "); 60 | if let Some(link) = Some(link_line) { 61 | if link.is_some() { 62 | stripped_link = link.as_ref().unwrap().to_string(); 63 | } 64 | } 65 | 66 | let file_name_str = format!("`{str_ip}`"); 67 | let mut code_path: String = prefix.to_owned(); 68 | code_path.push_str(&file_path); 69 | let file_name_code_path = code_path; 70 | code_str = make_href(file_name_str, file_name_code_path); 71 | } 72 | if !stripped_title.is_empty() && !stripped_link.is_empty() { 73 | let title_str = make_href(stripped_title, stripped_link); 74 | let mut final_str = count.to_string() + ". " + &title_str + ": "; 75 | final_str.push_str(&code_str); 76 | file.write_all(final_str.as_bytes())?; 77 | file.write_all(b"\n")?; 78 | count += 1; 79 | } 80 | } 81 | } 82 | } 83 | } 84 | 85 | file.write_all(readme_suffix.as_bytes())?; 86 | file.write_all(b"\n\n")?; 87 | file.write_all(acknowledge.as_bytes())?; 88 | file.flush()?; 89 | Ok(()) 90 | } 91 | 92 | fn read_lines

(filename: P) -> io::Result>> 93 | where 94 | P: AsRef, 95 | { 96 | let file = File::open(filename)?; 97 | Ok(io::BufReader::new(file).lines()) 98 | } 99 | --------------------------------------------------------------------------------