Nov LeetCoding Challenge Rust Solution
Table of Contents
1706. Where Will the Ball Fall⌗
impl Solution {
pub fn find_ball(grid: Vec<Vec<i32>>) -> Vec<i32> {
let m = grid[0].len();
let mut ret = vec![0; m];
fn internal(grid: &Vec<Vec<i32>>, i: usize, j: usize) -> i32 {
if i == grid.len() {
return j as i32;
}
if grid[i][j] == 1 && (j + 1 >= grid[0].len() || grid[i][j + 1] == -1) {
return -1;
}
if grid[i][j] == -1 && (j as i32 - 1 < 0 || grid[i][j - 1] == 1) {
return -1;
}
if grid[i][j] == 1 {
internal(grid, i + 1, j + 1)
} else {
internal(grid, i + 1, j - 1)
}
}
for j in 0..m {
ret[j] = internal(&grid, 0, j);
}
ret
}
}
433. Minimum Genetic Mutation⌗
use std::collections::{HashSet, VecDeque};
impl Solution {
pub fn min_mutation(start: String, end: String, bank: Vec<String>) -> i32 {
let choices = ["A", "C", "G", "T"];
let mut bank_set: HashSet<String> = bank.into_iter().collect();
let mut queue = VecDeque::new();
queue.push_back(start);
let mut ret = 0;
while !queue.is_empty() {
let size = queue.len();
for _ in 0..size {
let curr = queue.pop_front().unwrap();
if curr == end {
return ret;
}
for i in 0..curr.len() {
let mut next = curr.clone();
for choice in choices {
next.replace_range(i..=i, choice);
if !bank_set.contains(&next) {
continue;
}
bank_set.remove(&next);
queue.push_back(next.clone());
}
}
}
ret += 1;
}
-1
}
}
2131. Longest Palindrome by Concatenating Two Letter Words⌗
use std::collections::HashMap;
impl Solution {
pub fn longest_palindrome(words: Vec<String>) -> i32 {
let mut counter = HashMap::new();
let mut ret = 0;
for word in words.iter() {
let rev_word = word.chars().rev().collect::<String>();
let rev_cnt = counter.entry(rev_word).or_insert(0);
if *rev_cnt > 0 {
ret += 4;
*rev_cnt -= 1;
} else {
*counter.entry(word.clone()).or_insert(0) += 1;
}
}
for word in words.iter() {
let bytes = word.as_bytes();
if bytes[0] == bytes[1] && counter[word] > 0 {
ret += 2;
break;
}
}
ret
}
}
212. Word Search II⌗
use std::collections::{HashMap, HashSet};
const DIRS: [[i32; 2]; 4] = [[0, 1], [1, 0], [0, -1], [-1, 0]];
struct Trie {
is_word: bool,
children: HashMap<char, Trie>,
}
impl Trie {
pub fn new() -> Self {
Trie {
is_word: false,
children: HashMap::new(),
}
}
pub fn insert(&mut self, word: &str) {
let mut node = self;
for c in word.chars() {
let child = node.children.entry(c).or_insert_with(Trie::new);
node = child;
}
node.is_word = true;
}
}
impl Solution {
pub fn find_words(mut board: Vec<Vec<char>>, words: Vec<String>) -> Vec<String> {
let mut trie = Trie::new();
for word in &words {
trie.insert(word);
}
fn internal(
board: &mut Vec<Vec<char>>,
i: i32,
j: i32,
mut node: &Trie,
path: &mut String,
ret: &mut HashSet<String>,
) {
if i < 0 || i >= board.len() as i32 || j < 0 || j >= board[0].len() as i32 {
return;
}
let iu = i as usize;
let ju = j as usize;
if board[iu][ju] == '#' {
return;
}
if let Some(child) = node.children.get(&board[iu][ju]) {
node = child;
} else {
return;
}
let v = board[iu][ju];
board[iu][ju] = '#';
path.push(v);
if node.is_word {
ret.insert(path.clone());
}
for dir in DIRS {
internal(board, i + dir[0], j + dir[1], node, path, ret);
}
path.pop();
board[iu][ju] = v;
}
let mut ret = HashSet::new();
let mut path = "".to_string();
for i in 0..board.len() as i32 {
for j in 0..board[0].len() as i32 {
internal(&mut board, i, j, &trie, &mut path, &mut ret);
}
}
ret.into_iter().collect()
}
}
899. Orderly Queue⌗
impl Solution {
pub fn orderly_queue(s: String, k: i32) -> String {
if k == 1 {
let mut ret = s.clone();
for i in 1..s.len() {
let l = &s[0..i];
let r = &s[i..];
let t = format!("{}{}", r, l);
if t < ret {
ret = t;
}
}
ret
} else {
let mut s: Vec<char> = s.chars().collect();
s.sort();
s.into_iter().collect()
}
}
}
1323. Maximum 69 Number⌗
impl Solution {
pub fn maximum69_number (num: i32) -> i32 {
let mut s = num.to_string();
if let Some(index) = s.find('6') {
s.replace_range(index..=index, "9");
return s.parse().unwrap();
}
num
}
}
1544. Make The String Great⌗
impl Solution {
pub fn make_good(s: String) -> String {
let mut ret = "".to_string();
for c in s.chars() {
let revc = if c.is_ascii_lowercase() {
c.to_ascii_uppercase()
} else {
c.to_ascii_lowercase()
};
if !ret.is_empty() && ret.ends_with(revc) {
ret.pop();
} else {
ret.push(c);
}
}
ret
}
}
901. Online Stock Span⌗
struct StockSpanner {
prices: Vec<i32>,
stack: Vec<usize>,
cache: Vec<i32>,
}
impl StockSpanner {
fn new() -> Self {
StockSpanner {
prices: Vec::new(),
stack: Vec::new(),
cache: Vec::new(),
}
}
fn next(&mut self, price: i32) -> i32 {
self.prices.push(price);
let last_index = self.prices.len() - 1;
let mut index = last_index;
while let Some(&peek) = self.stack.last() {
if price >= self.prices[peek] {
index = self.stack.pop().unwrap();
} else {
break;
}
}
self.stack.push(last_index);
let ret = (last_index - index + 1) as i32 + (self.cache.get(index).unwrap_or(&1) - 1);
self.cache.push(ret);
ret
}
}
1047. Remove All Adjacent Duplicates In String⌗
impl Solution {
pub fn remove_duplicates(s: String) -> String {
let mut ret = "".to_string();
for c in s.chars() {
if ret.ends_with(c) {
ret.pop();
} else {
ret.push(c);
}
}
ret
}
}
26. Remove Duplicates from Sorted Array⌗
impl Solution {
pub fn remove_duplicates(nums: &mut Vec<i32>) -> i32 {
let mut j = 0;
for i in 0..nums.len() {
if nums[i] != nums[j] {
j += 1;
nums[j] = nums[i];
}
}
(j + 1) as i32
}
}
295. Find Median from Data Stream⌗
use std::cmp::{Ordering, Reverse};
use std::collections::BinaryHeap;
struct MedianFinder {
left: BinaryHeap<Reverse<i32>>,
right: BinaryHeap<i32>,
}
impl MedianFinder {
fn new() -> Self {
MedianFinder {
left: BinaryHeap::new(),
right: BinaryHeap::new(),
}
}
fn add_num(&mut self, num: i32) {
self.left.push(Reverse(num));
self.right.push(self.left.pop().unwrap().0);
if self.right.len() > self.left.len() {
self.left.push(Reverse(self.right.pop().unwrap()));
}
}
fn find_median(&self) -> f64 {
match self.left.len().cmp(&self.right.len()) {
Ordering::Less => *self.right.peek().unwrap() as f64,
Ordering::Equal => (self.left.peek().unwrap().0 + self.right.peek().unwrap()) as f64 / 2.0,
Ordering::Greater => self.left.peek().unwrap().0 as f64
}
}
}
151. Reverse Words in a String⌗
impl Solution {
pub fn reverse_words(s: String) -> String {
s.split(' ')
.filter(|word| word != &"")
.rev()
.collect::<Vec<&str>>()
.join(" ")
}
}
947. Most Stones Removed with Same Row or Column⌗
struct UnionFind {
parent: Vec<usize>,
rank: Vec<usize>,
}
impl UnionFind {
fn new(n: usize) -> Self {
let mut parent = vec![0; n];
let rank = vec![0; n];
for i in 0..parent.len() {
parent[i] = i;
}
Self { parent, rank }
}
fn union(&mut self, u: usize, v: usize) -> bool {
let pu = self.find(u);
let pv = self.find(v);
if pu == pv {
return false;
}
if self.rank[pu] < self.rank[pv] {
self.parent[pu] = pv;
} else {
self.parent[pv] = pu;
if self.rank[pv] == self.rank[pu] {
self.rank[pv] += 1;
}
}
true
}
fn find(&mut self, u: usize) -> usize {
if self.parent[u] == u {
return u;
}
self.parent[u] = self.find(self.parent[u]);
self.parent[u]
}
}
impl Solution {
pub fn remove_stones(stones: Vec<Vec<i32>>) -> i32 {
let n = stones.len();
let mut ret: i32 = 0;
let mut uf = UnionFind::new(n);
for i in 0..n {
for j in (i + 1)..n {
if stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1] {
if uf.union(i, j) {
ret += 1;
}
}
}
}
ret
}
}
222. Count Complete Tree Nodes⌗
use std::rc::Rc;
use std::cell::RefCell;
impl Solution {
pub fn count_nodes(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
if let Some(root) = root {
let mut root = root.borrow_mut();
return Solution::count_nodes(root.left.take()) +
Solution::count_nodes(root.right.take()) + 1;
}
0
}
}
374. Guess Number Higher or Lower⌗
impl Solution {
unsafe fn guessNumber(n: i32) -> i32 {
let mut l = 0;
let mut r = n;
while l < r {
let m = l + (r - l) / 2;
if guess(m) == 1 {
l = m + 1;
} else {
r = m;
}
}
l
}
}
223. Rectangle Area⌗
impl Solution {
pub fn compute_area(
ax1: i32,
ay1: i32,
ax2: i32,
ay2: i32,
bx1: i32,
by1: i32,
bx2: i32,
by2: i32,
) -> i32 {
let cx1 = ax1.max(bx1);
let cy1 = ay1.max(by1);
let cx2 = ax2.min(bx2);
let cy2 = ay2.min(by2);
Solution::area(ax1, ay1, ax2, ay2) +
Solution::area(bx1, by1, bx2, by2) -
Solution::area(cx1, cy1, cx2, cy2)
}
fn area(x1: i32, y1: i32, x2: i32, y2: i32) -> i32 {
if x1 > x2 || y1 > y2 {
return 0;
}
(x2 - x1) * (y2 - y1)
}
}
263. Ugly Number⌗
impl Solution {
pub fn is_ugly(mut n: i32) -> bool {
if n < 1 {
return false;
}
while n & 1 == 0 {
n >>= 1;
}
while n % 3 == 0 {
n /= 3;
}
while n % 5 == 0 {
n /= 5
}
n == 1
}
}
587. Erect the Fence⌗
impl Solution {
pub fn outer_trees(mut points: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let p0 = &points
.iter()
.min_by(|a, b| a[1].cmp(&b[1]).then(a[0].cmp(&b[0])))
.unwrap()
.clone();
points.sort_by(|a, b| {
angle(p0, a)
.partial_cmp(&angle(p0, b))
.unwrap()
.then(dist(p0, a).cmp(&dist(p0, b)))
});
let n = points.len();
let mut i = (n - 1) as i32;
while i >= 0 && orientation(p0, &points[n - 1], &points[i as usize]) == 0 {
i -= 1;
}
reverse(&mut points, (i + 1) as usize, n - 1);
let mut stack: Vec<Vec<i32>> = vec![];
for p in points {
while stack.len() >= 2
&& orientation(&stack[stack.len() - 2], &stack[stack.len() - 1], &p) < 0
{
stack.pop();
}
stack.push(p);
}
stack
}
}
fn reverse(points: &mut Vec<Vec<i32>>, mut l: usize, mut r: usize) {
while l < r {
points.swap(l, r);
l += 1;
r -= 1;
}
}
fn angle(p0: &[i32], p1: &[i32]) -> f32 {
((p1[1] - p0[1]) as f32).atan2((p1[0] - p0[0]) as f32)
}
fn dist(p0: &[i32], p1: &[i32]) -> i32 {
(p1[0] - p0[0]).pow(2) + (p1[1] - p0[1]).pow(2)
}
fn orientation(p0: &[i32], p1: &[i32], p2: &[i32]) -> i32 {
(p2[1] - p1[1]) * (p1[0] - p0[0]) - (p1[1] - p0[1]) * (p2[0] - p1[0])
}
224. Basic Calculator⌗
impl Solution {
pub fn calculate(s: String) -> i32 {
let expr = s
.chars()
.filter(|it| !it.is_ascii_whitespace())
.collect::<Vec<char>>();
Calculator::new(expr).eval()
}
}
struct Calculator {
expr: Vec<char>,
index: usize,
}
// grammar
// term: unary (('+' / '-') unary)*
// unary: '-'? group
// group: '(' term ')' | number
// number: ('0' - '9')+
impl Calculator {
pub fn new(expr: Vec<char>) -> Self {
Self { expr, index: 0 }
}
pub fn eval(&mut self) -> i32 {
self.term()
}
fn term(&mut self) -> i32 {
let mut ret = self.unary();
while self.is_match('+') || self.is_match('-') {
if self.is_match('+') {
self.advance();
ret += self.unary();
} else {
self.advance();
ret -= self.unary();
}
}
ret
}
fn unary(&mut self) -> i32 {
if self.is_match('-') {
self.advance();
return -self.group();
}
self.group()
}
fn group(&mut self) -> i32 {
if self.is_match('(') {
self.advance();
let ret = self.term();
self.advance();
return ret;
}
self.number()
}
fn number(&mut self) -> i32 {
let mut num: i32 = 0;
while self.peek() >= '0' && self.peek() <= '9' {
num = num * 10 + (self.peek() as u8 - b'0') as i32;
self.advance();
}
num
}
fn advance(&mut self) {
self.index += 1
}
fn is_match(&self, c: char) -> bool {
self.peek() == c
}
fn peek(&self) -> char {
if self.index >= self.expr.len() {
return '\0';
}
self.expr[self.index]
}
}
1926. Nearest Exit from Entrance in Maze⌗
use std::collections::VecDeque;
impl Solution {
pub fn nearest_exit(maze: Vec<Vec<char>>, entrance: Vec<i32>) -> i32 {
let (m, n) = (maze.len(), maze[0].len());
let mut queue = VecDeque::new();
let mut visited = vec![vec![false; n]; m];
queue.push_back((entrance[0], entrance[1]));
visited[entrance[0] as usize][entrance[1] as usize] = true;
let dirs = [[0, 1], [1, 0], [0, -1], [-1, 0]];
let mut ret = 0;
while !queue.is_empty() {
ret += 1;
for _ in 0..queue.len() {
let u = queue.pop_front().unwrap();
for dir in dirs {
let i = u.0 + dir[0];
let j = u.1 + dir[1];
if i < 0 || i >= m as i32 || j < 0 || j >= n as i32 {
continue;
}
if visited[i as usize][j as usize] || maze[i as usize][j as usize] == '+' {
continue;
}
if i == 0 || i == (m - 1) as i32 || j == 0 || j == (n - 1) as i32 {
return ret;
}
queue.push_back((i, j));
visited[i as usize][j as usize] = true;
}
}
}
-1
}
}
279. Perfect Squares⌗
use std::collections::VecDeque;
impl Solution {
pub fn num_squares(n: i32) -> i32 {
let n = n as usize;
let mut queue = VecDeque::new();
let mut visited = vec![false; n + 1];
queue.push_back(n);
visited[n] = true;
let mut ret = 0;
while !queue.is_empty() {
ret += 1;
for _ in 0..queue.len() {
let u = queue.pop_front().unwrap();
for i in 1..=u {
if u < i * i {
break;
}
let v = u - i * i;
if v == 0 {
return ret;
}
if visited[v] {
continue;
}
queue.push_back(v);
visited[v] = true;
}
}
}
-1
}
}
36. Valid Sudoku⌗
impl Solution {
pub fn is_valid_sudoku(board: Vec<Vec<char>>) -> bool {
let n = board.len();
let mut row = vec![0; n];
let mut col = vec![0; n];
let mut cel = vec![0; n];
for i in 0..n {
for j in 0..n {
if board[i][j] != '.' {
let k = (i / 3) * 3 + (j / 3);
let mask = 1 << (board[i][j] as u8 - b'0');
if row[i] & mask != 0 || col[j] & mask != 0 || cel[k] & mask != 0 {
return false;
}
row[i] |= mask;
col[j] |= mask;
cel[k] |= mask;
}
}
}
true
}
}
79. Word Search⌗
const DIRS: [[i32; 2]; 4] = [[0, 1], [1, 0], [0, -1], [-1, 0]];
struct Env {
board: Vec<Vec<char>>,
word: Vec<char>,
m: i32,
n: i32,
}
impl Solution {
pub fn exist(board: Vec<Vec<char>>, word: String) -> bool {
fn internal(env: &mut Env, i: i32, j: i32, k: usize) -> bool {
if k == env.word.len() {
return true;
}
if i < 0 || i >= env.m || j < 0 || j >= env.n {
return false;
}
let (ui, uj) = (i as usize, j as usize);
let v = env.board[ui][uj];
if v == '#' || v != env.word[k] {
return false;
}
env.board[ui][uj] = '#';
for dir in DIRS {
if internal(env, i + dir[0], j + dir[1], k + 1) {
return true;
}
}
env.board[ui][uj] = v;
false
}
let (m, n) = (board.len() as i32, board[0].len() as i32);
let word = word.chars().collect::<Vec<char>>();
let mut env = Env { board, word, m, n };
for i in 0..m {
for j in 0..n {
if internal(&mut env, i as i32, j as i32, 0) {
return true;
}
}
}
false
}
}
1235. Maximum Profit in Job Scheduling⌗
struct Job {
start_time: i32,
end_time: i32,
profit: i32,
}
impl Job {
fn new(start_time: i32, end_time: i32, profit: i32) -> Self {
Self {
start_time,
end_time,
profit,
}
}
}
impl Solution {
pub fn job_scheduling(start_time: Vec<i32>, end_time: Vec<i32>, profit: Vec<i32>) -> i32 {
let n = start_time.len();
let mut jobs = vec![];
for i in 0..n {
jobs.push(Job::new(start_time[i], end_time[i], profit[i]));
}
jobs.sort_by(|a, b| a.end_time.cmp(&b.end_time));
let mut dp = vec![0; n];
dp[0] = jobs[0].profit;
for i in 1..n {
let job = &jobs[i];
let (mut l, mut r) = (0, i);
while l < r {
let m = l + (r - l) / 2;
if jobs[m].end_time <= job.start_time {
l = m + 1;
} else {
r = m;
}
}
let valid = l > 0 && l <= i;
dp[i] = dp[i - 1].max(job.profit + if valid { dp[l - 1] } else { 0 });
}
dp[n - 1]
}
}
446. Arithmetic Slices II - Subsequence⌗
use std::collections::HashMap;
struct Env {
n: usize,
nums: Vec<i32>,
memo: HashMap<i64, i32>,
}
impl Solution {
pub fn number_of_arithmetic_slices(nums: Vec<i32>) -> i32 {
fn dp(env: &mut Env, diff: i64, i: usize) -> i32 {
let key = diff << 32 | i as i64;
if let Some(&ret) = env.memo.get(&key) {
return ret;
}
let mut ret = 0;
for j in (i + 1)..env.n {
if (env.nums[j] as i64 - env.nums[i] as i64) == diff as i64 {
ret += dp(env, diff, j) + 1;
}
}
env.memo.entry(key).or_insert(ret);
ret
}
let n = nums.len();
let mut env = Env {
n: nums.len(),
nums: nums.clone(),
memo: HashMap::new(),
};
let mut ret = 0;
for i in 0..n {
for j in (i + 1)..n {
let diff = nums[j] as i64 - nums[i] as i64;
ret += dp(&mut env, diff, j);
}
}
ret
}
}
2225. Find Players With Zero or One Losses⌗
impl Solution {
pub fn find_winners(matches: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let n = 100001;
let mut in_degree = vec![0; n];
let mut in_match = vec![false; n];
for edge in matches {
let (u, v) = (edge[0] as usize, edge[1] as usize);
in_degree[v] += 1;
in_match[u] = true;
in_match[v] = true;
}
let mut ret = vec![vec![]; 2];
for i in 0..n {
if !in_match[i] {
continue;
}
if in_degree[i] == 0 {
ret[0].push(i as i32);
} else if in_degree[i] == 1 {
ret[1].push(i as i32);
}
}
ret
}
}
380. Insert Delete GetRandom O(1)⌗
use std::collections::HashMap;
use rand::prelude::*;
struct RandomizedSet {
index_map: HashMap<i32, usize>,
nums: Vec<i32>,
}
impl RandomizedSet {
fn new() -> Self {
Self {
index_map: HashMap::new(),
nums: Vec::new(),
}
}
fn insert(&mut self, val: i32) -> bool {
if self.index_map.contains_key(&val) {
return false;
}
self.nums.push(val);
self.index_map.entry(val).or_insert(self.nums.len() - 1);
true
}
fn remove(&mut self, val: i32) -> bool {
if !self.index_map.contains_key(&val) {
return false;
}
let at = self.index_map[&val];
let last_index = self.nums.len() - 1;
self.nums.swap(at, last_index);
self.index_map.entry(self.nums[at]).and_modify(|v| *v = at);
self.index_map.remove(&self.nums[last_index]);
self.nums.remove(last_index);
true
}
fn get_random(&self) -> i32 {
let at = thread_rng().gen_range(0..self.nums.len());
self.nums[at]
}
}
1207. Unique Number of Occurrences⌗
impl Solution {
pub fn unique_occurrences(arr: Vec<i32>) -> bool {
let n = 1001;
let offset = 1000;
let mut count = vec![0; offset + n];
for num in arr {
count[(num + offset as i32) as usize] += 1;
}
let mut set = vec![false; offset + n];
for c in count {
if c != 0 {
if set[c] {
return false;
}
set[c] = true;
}
}
true
}
}
Read other posts