Dec LeetCoding Challenge Rust Solution
Table of Contents
1704. Determine if String Halves Are Alike⌗
impl Solution {
pub fn halves_are_alike(s: String) -> bool {
let s = s.chars().collect::<Vec<char>>();
let n = s.len();
let m = n / 2;
Solution::count(&s, 0, m) == Solution::count(&s, m, n)
}
fn count(s: &[char], l: usize, r: usize) -> i32 {
let mut ret = 0;
for i in l..r {
let c = s[i].to_ascii_lowercase();
if c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' {
ret += 1;
}
}
ret
}
}
1657. Determine if Two Strings Are Close⌗
impl Solution {
pub fn close_strings(word1: String, word2: String) -> bool {
let n = 26;
let mut cnt1 = vec![0; n];
let mut cnt2 = vec![0; n];
for &c in word1.as_bytes() {
cnt1[(c - b'a') as usize] += 1;
}
for &c in word2.as_bytes() {
cnt2[(c - b'a') as usize] += 1;
}
for c in 0..n {
if cnt1[c] != 0 && cnt2[c] == 0 || cnt2[c] != 0 && cnt1[c] == 0 {
return false;
}
}
cnt1.sort();
cnt2.sort();
for c in 0..n {
if cnt1[c] != cnt2[c] {
return false;
}
}
true
}
}
451. Sort Characters By Frequency⌗
impl Solution {
pub fn frequency_sort(s: String) -> String {
let n = 128;
let mut freq = vec![0; n];
let mut chars = (0..n).collect::<Vec<usize>>();
for &c in s.as_bytes() {
freq[c as usize] += 1;
}
chars.sort_by(|&a, &b| freq[b].cmp(&freq[a]));
let mut ret = "".to_string();
for c in chars {
let f = freq[c];
let c = c as u8;
for _ in 0..f {
ret.push(c.into());
}
}
ret
}
}
2256. Minimum Average Difference⌗
impl Solution {
pub fn minimum_average_difference(nums: Vec<i32>) -> i32 {
let n = nums.len();
let mut left_sum = vec![0 as i64; n + 1];
for i in 1..=n {
left_sum[i] = left_sum[i - 1] + nums[i - 1] as i64;
}
let mut ret = 0;
let mut min_abs = i64::MAX;
let mut right_sum = 0;
for i in (0..n).rev() {
let left_avg = left_sum[i + 1] / (i - 0 + 1) as i64;
let right_avg = right_sum / ((n - 1) - (i + 1) + 1).max(1) as i64;
let abs = (left_avg - right_avg).abs();
if abs <= min_abs {
ret = i;
min_abs = abs;
}
right_sum += nums[i] as i64;
}
ret as i32
}
}
876. Middle of the Linked List⌗
impl Solution {
pub fn middle_node(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut slow = head.clone();
let mut fast = head;
while fast.is_some() && fast.as_ref().unwrap().next.is_some() {
slow = slow.unwrap().next;
fast = fast.unwrap().next.unwrap().next;
}
slow
}
}
328. Odd Even Linked List⌗
impl Solution {
pub fn odd_even_list(mut head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut odd = None;
let mut even = None;
let mut odd_iter = &mut odd;
let mut even_iter = &mut even;
let mut is_odd = true;
while let Some(mut node) = head {
head = node.next;
node.next = None;
if is_odd {
odd_iter = &mut odd_iter.insert(node).next;
} else {
even_iter = &mut even_iter.insert(node).next;
}
is_odd ^= true;
}
if let Some(node) = even {
odd_iter.insert(node);
}
odd
}
}
938. Range Sum of BST⌗
use std::cell::RefCell;
use std::rc::Rc;
type Node = Option<Rc<RefCell<TreeNode>>>;
impl Solution {
pub fn range_sum_bst(root: Node, low: i32, high: i32) -> i32 {
fn f(root: &Node, low: i32, high: i32) -> i32 {
if let Some(root) = root {
let root = root.borrow();
if root.val < low {
return f(&root.right, low, high);
}
if root.val > high {
return f(&root.left, low, high);
}
return f(&root.left, low, high) + f(&root.right, low, high) + root.val;
}
0
}
f(&root, low, high)
}
}
872. Leaf-Similar Trees⌗
use std::cell::RefCell;
use std::rc::Rc;
type Node = Option<Rc<RefCell<TreeNode>>>;
impl Solution {
pub fn leaf_similar(root1: Node, root2: Node) -> bool {
fn collect_leaf(root: &Node, to: &mut Vec<i32>) {
if let Some(root) = root {
let root = root.borrow();
if root.left.is_none() && root.right.is_none() {
to.push(root.val);
return;
}
collect_leaf(&root.left, to);
collect_leaf(&root.right, to);
}
}
let mut leaf1 = vec![];
let mut leaf2 = vec![];
collect_leaf(&root1, &mut leaf1);
collect_leaf(&root2, &mut leaf2);
leaf1.cmp(&leaf2).is_eq()
}
}
1026. Maximum Difference Between Node and Ancestor⌗
use std::cell::RefCell;
use std::rc::Rc;
type Node = Option<Rc<RefCell<TreeNode>>>;
impl Solution {
pub fn max_ancestor_diff(root: Node) -> i32 {
fn f(root: &Node, mut min: i32, mut max: i32) -> i32 {
if let Some(root) = root {
let root = root.borrow();
min = min.min(root.val);
max = max.max(root.val);
return f(&root.left, min, max).max(f(&root.right, min, max));
}
max - min
}
let v = root.as_ref().unwrap().borrow().val;
f(&root, v, v)
}
}
1339. Maximum Product of Splitted Binary Tree⌗
use std::cell::RefCell;
use std::rc::Rc;
type Node = Option<Rc<RefCell<TreeNode>>>;
impl Solution {
pub fn max_product(root: Node) -> i32 {
fn sum(root: &Node) -> i32 {
if let Some(root) = root {
let root = root.borrow();
return sum(&root.left) + sum(&root.right) + root.val;
}
0
}
fn product(root: &Node, total_sum: i32) -> (i32, i64) {
if let Some(root) = root {
let root = root.borrow();
let left = product(&root.left, total_sum);
let right = product(&root.right, total_sum);
let s = (left.0 + right.0) + root.val;
let p = s as i64 * (total_sum - s) as i64;
return (s, left.1.max(right.1).max(p));
}
(0, 0)
}
let total_sum = sum(&root);
(product(&root, total_sum).1 % (1_000_000_007)) as i32
}
}
124. Binary Tree Maximum Path Sum⌗
use std::cell::RefCell;
use std::rc::Rc;
type Node = Option<Rc<RefCell<TreeNode>>>;
impl Solution {
pub fn max_path_sum(root: Node) -> i32 {
fn f(root: &Node, ret: &mut i32) -> i32 {
if let Some(root) = root {
let root = root.borrow();
let l = f(&root.left, ret);
let r = f(&root.right, ret);
*ret = (*ret)
.max(root.val)
.max(l + root.val)
.max(r + root.val)
.max(l + r + root.val);
return root.val.max(root.val + l).max(root.val + r);
}
0
}
let mut ret = i32::MIN >> 1;
f(&root, &mut ret);
ret
}
}
70. Climbing Stairs⌗
impl Solution {
pub fn climb_stairs(n: i32) -> i32 {
let n = n as usize;
let mut dp = vec![1; n + 1];
for i in 2..=n {
dp[i] = dp[i - 1] + dp[i - 2];
}
dp[n]
}
}
931. Minimum Falling Path Sum⌗
struct Env {
matrix: Vec<Vec<i32>>,
memo: Vec<Vec<i32>>,
}
impl Solution {
pub fn min_falling_path_sum(matrix: Vec<Vec<i32>>) -> i32 {
fn f(env: &mut Env, i: i32, j: i32) -> i32 {
if i >= env.matrix.len() as i32 {
return 0;
}
if j < 0 || j >= env.matrix.len() as i32 {
return i32::MAX >> 1;
}
let (iu, ju) = (i as usize, j as usize);
if env.memo[iu][ju] != -1 {
return env.memo[iu][ju];
}
env.memo[iu][ju] = f(env, i + 1, j - 1).min(f(env, i + 1, j)).min(f(env, i + 1, j + 1)) + env.matrix[iu][ju];
env.memo[iu][ju]
}
let (m, n) = (matrix.len(), matrix[0].len());
let mut ret = i32::MAX >> 1;
let mut env = Env {
matrix,
memo: vec![vec![-1; n]; m]
};
for j in 0..n {
ret = ret.min(f(&mut env, 0, j as i32));
}
ret
}
}
198. House Robber⌗
impl Solution {
pub fn rob(nums: Vec<i32>) -> i32 {
let n = nums.len();
let mut dp = vec![0; n];
dp[0] = nums[0];
if n > 1 {
dp[1] = nums[0].max(nums[1]);
}
for i in 2..n {
dp[i] = dp[i - 1].max(dp[i - 2] + nums[i]);
}
dp[n - 1]
}
}
1143. Longest Common Subsequence⌗
impl Solution {
pub fn longest_common_subsequence(text1: String, text2: String) -> i32 {
let (s1, s2) = (text1.as_bytes(), text2.as_bytes());
let (m, n) = (s1.len(), s2.len());
let mut dp = vec![vec![0; n + 1]; m + 1];
for i in 1..=m {
for j in 1..=n {
if s1[i - 1] == s2[j - 1] {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = dp[i - 1][j].max(dp[i][j - 1]);
}
}
}
dp[m][n]
}
}
232. Implement Queue using Stacks⌗
struct MyQueue {
stack1: Vec<i32>,
stack2: Vec<i32>
}
impl MyQueue {
fn new() -> Self {
Self {
stack1: vec![],
stack2: vec![],
}
}
fn push(&mut self, x: i32) {
self.stack1.push(x);
}
fn pop(&mut self) -> i32 {
if self.peek() != -1 {
return self.stack2.pop().unwrap();
}
-1
}
fn peek(&mut self) -> i32 {
if self.stack2.is_empty() {
while let Some(v) = self.stack1.pop() {
self.stack2.push(v);
}
}
if self.stack2.is_empty() {
return -1
}
self.stack2[self.stack2.len() - 1]
}
fn empty(&self) -> bool {
self.stack1.is_empty() && self.stack2.is_empty()
}
}
150. Evaluate Reverse Polish Notation⌗
use std::ops::{Add, Div, Mul, Sub};
impl Solution {
pub fn eval_rpn(tokens: Vec<String>) -> i32 {
let mut stack = vec![];
fn eval(stack: &mut Vec<i32>, op: impl Fn(i32, i32) -> i32) {
let b = stack.pop().unwrap();
let a = stack.pop().unwrap();
stack.push(op(a, b));
}
for token in tokens {
match token.as_str() {
"+" => eval(&mut stack, Add::add),
"-" => eval(&mut stack, Sub::sub),
"*" => eval(&mut stack, Mul::mul),
"/" => eval(&mut stack, Div::div),
_ => stack.push(token.parse().unwrap())
}
}
stack.pop().unwrap()
}
}
739. Daily Temperatures⌗
impl Solution {
pub fn daily_temperatures(temperatures: Vec<i32>) -> Vec<i32> {
let n = temperatures.len();
let mut ret = vec![0; n];
let mut stack = vec![];
for (i, &t) in temperatures.iter().enumerate() {
while let Some(&j) = stack.last() {
if t > temperatures[j] {
stack.pop();
ret[j] = (i - j) as i32;
} else {
break;
}
}
stack.push(i);
}
ret
}
}
1971. Find if Path Exists in Graph⌗
struct UnionFind {
parent: Vec<usize>,
rank: Vec<usize>,
}
impl UnionFind {
fn new(n: usize) -> Self {
Self {
parent: (0..n).collect::<Vec<usize>>(),
rank: vec![0; n],
}
}
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]
}
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[pu] == self.rank[pv] {
self.rank[pu] += 1;
}
}
true
}
}
impl Solution {
pub fn valid_path(n: i32, edges: Vec<Vec<i32>>, source: i32, destination: i32) -> bool {
let mut uf = UnionFind::new(n as usize);
for edge in edges {
let (u, v) = (edge[0] as usize, edge[1] as usize);
uf.union(u, v);
}
uf.find(source as usize) == uf.find(destination as usize)
}
}
841. Keys and Rooms⌗
use std::collections::HashSet;
impl Solution {
pub fn can_visit_all_rooms(rooms: Vec<Vec<i32>>) -> bool {
fn f(u: i32, rooms: &Vec<Vec<i32>>, visited: &mut HashSet<i32>) {
if visited.contains(&u) {
return;
}
visited.insert(u);
for &v in &rooms[u as usize] {
f(v, rooms, visited);
}
}
let mut visited = HashSet::new();
f(0, &rooms, &mut visited);
visited.len() == rooms.len()
}
}
886. Possible Bipartition⌗
struct UnionFind {
parent: Vec<usize>,
rank: Vec<usize>,
}
impl UnionFind {
fn new(n: usize) -> Self {
Self {
parent: (0..n).collect::<Vec<usize>>(),
rank: vec![0; n],
}
}
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]
}
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[pu] == self.rank[pv] {
self.rank[pu] += 1;
}
}
true
}
}
impl Solution {
pub fn possible_bipartition(n: i32, dislikes: Vec<Vec<i32>>) -> bool {
let n = n as usize;
let mut graph = vec![vec![]; n];
for d in dislikes {
let (u, v) = (d[0] as usize - 1, d[1] as usize - 1);
graph[u].push(v);
graph[v].push(u);
}
let mut uf = UnionFind::new(n);
for i in 0..n {
let next = &graph[i];
if next.is_empty() {
continue;
}
let u = next[0];
for &v in next {
if uf.find(i) == uf.find(v) {
return false;
}
uf.union(u, v);
}
}
true
}
}
834. Sum of Distances in Tree⌗
struct Env {
count: Vec<i32>,
ret: Vec<i32>,
}
impl Solution {
pub fn sum_of_distances_in_tree(n: i32, edges: Vec<Vec<i32>>) -> Vec<i32> {
let n = n as usize;
let mut graph = vec![vec![]; n];
for edge in edges {
let (u, v) = (edge[0] as usize, edge[1] as usize);
graph[u].push(v);
graph[v].push(u);
}
let mut env = Env {
count: vec![1; n],
ret: vec![0; n]
};
fn f(env: &mut Env, graph: &Vec<Vec<usize>>, root: usize, parent: usize) {
for &child in &graph[root] {
if child == parent {
continue;
}
f(env, graph, child, root);
env.count[root] += env.count[child];
env.ret[root] += env.ret[child] + env.count[child];
}
}
fn g(env: &mut Env, graph: &Vec<Vec<usize>>, root: usize, parent: usize) {
for &child in &graph[root] {
if child == parent {
continue;
}
env.ret[child] = env.ret[root] + (env.count.len() as i32 - env.count[child]) - env.count[child];
g(env, graph, child, root);
}
}
f(&mut env, &graph, 0, n + 1);
g(&mut env, &graph, 0, n + 1);
env.ret
}
}
309. Best Time to Buy and Sell Stock with Cooldown⌗
impl Solution {
pub fn max_profit(prices: Vec<i32>) -> i32 {
let mut n = prices.len();
let mut dp = vec![vec![0; 3]; n];
dp[0][0] = -prices[0];
for i in 1..n {
dp[i][0] = dp[i - 1][0].max(dp[i - 1][2] - prices[i]);
dp[i][1] = dp[i - 1][1].max(dp[i - 1][0] + prices[i]);
dp[i][2] = dp[i - 1][2].max(dp[i - 1][1]);
}
dp[n - 1][1].max(dp[n - 1][2])
}
}
790. Domino and Tromino Tiling⌗
impl Solution {
pub fn num_tilings(n: i32) -> i32 {
let n = n as usize;
let mut dp: Vec<Vec<i64>> = vec![vec![0; 3]; n + 1];
let m = 1_000_000_007;
dp[0][0] = 1;
dp[1][0] = 1;
for i in 2..=n {
dp[i][0] = (dp[i - 1][0] + dp[i - 2][0] + dp[i - 1][1] + dp[i - 1][2]) % m;
dp[i][1] = (dp[i - 2][0] + dp[i - 1][2]) % m;
dp[i][2] = (dp[i - 2][0] + dp[i - 1][1]) % m;
}
dp[n][0] as i32
}
}
2389. Longest Subsequence With Limited Sum⌗
impl Solution {
pub fn answer_queries(mut nums: Vec<i32>, queries: Vec<i32>) -> Vec<i32> {
nums.sort();
let (n, m) = (nums.len(), queries.len());
let mut presum = vec![0; n + 1];
for i in 1..=n {
presum[i] = presum[i - 1] + nums[i - 1];
}
fn bsearch(arr: &Vec<i32>, a: i32) -> usize {
let (mut l, mut r) = (0, arr.len());
while l < r {
let m = l + (r - l) / 2;
if arr[m] <= a {
l = m + 1;
} else {
r = m;
}
}
l
}
let mut ret = vec![0; m];
for i in 0..m {
ret[i] = (bsearch(&presum, queries[i]) - 1) as i32;
}
ret
}
}
55. Jump Game⌗
impl Solution {
pub fn can_jump(nums: Vec<i32>) -> bool {
let n = nums.len();
let mut dp = vec![false; n];
dp[0] = true;
for i in 1..n {
for j in (0..i).rev() {
if nums[j] as usize >= i - j && dp[j] {
dp[i] = true;
break;
}
}
}
dp[n - 1]
}
}
2279. Maximum Bags With Full Capacity of Rocks⌗
impl Solution {
pub fn maximum_bags(capacity: Vec<i32>, rocks: Vec<i32>, mut additional_rocks: i32) -> i32 {
let mut needs = capacity
.iter()
.zip(rocks)
.map(|(c, r)| c - r)
.collect::<Vec<i32>>();
needs.sort();
let mut ret = 0;
for need in needs {
if additional_rocks < need {
break;
}
additional_rocks -= need;
ret += 1;
}
ret
}
}
1962. Remove Stones to Minimize the Total⌗
use std::collections::BinaryHeap;
impl Solution {
pub fn min_stone_sum(piles: Vec<i32>, k: i32) -> i32 {
let mut max_heap = BinaryHeap::from(piles);
for _ in 0..k {
let p = max_heap.pop().unwrap();
max_heap.push(p - (p / 2));
}
max_heap.iter().sum()
}
}
1834. Single-Threaded CPU⌗
use std::{collections::BinaryHeap, cmp::Ordering};
#[derive(PartialEq, Eq, Default)]
struct Task {
enqueue_time: i32,
processing_time: i32,
index: i32,
}
impl Ord for Task {
fn cmp(&self, other: &Self) -> Ordering {
let r = self.processing_time.cmp(&other.processing_time).reverse();
if r == Ordering::Equal {
return self.index.cmp(&other.index).reverse();
}
r
}
}
impl PartialOrd for Task {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Solution {
pub fn get_order(tasks: Vec<Vec<i32>>) -> Vec<i32> {
let mut tasks = tasks
.into_iter()
.enumerate()
.map(|(index, task)| {
Task {
enqueue_time: task[0],
processing_time: task[1],
index: index as i32
}
})
.collect::<Vec<Task>>();
tasks.sort_by(|a, b| a.enqueue_time.cmp(&b.enqueue_time));
let mut cpu = BinaryHeap::new();
let n = tasks.len();
let mut ret = vec![];
let (mut i, mut t) = (0, 0);
while ret.len() < n {
while i < n && tasks[i].enqueue_time <= t {
cpu.push(&tasks[i]);
i += 1;
}
if cpu.is_empty() {
t = tasks[i].enqueue_time;
continue;
}
let task = cpu.pop().unwrap();
ret.push(task.index);
t += task.processing_time;
}
ret
}
}
797. All Paths From Source to Target⌗
impl Solution {
pub fn all_paths_source_target(graph: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
fn f(graph: &Vec<Vec<i32>>, u: i32, path: &mut Vec<i32>, paths: &mut Vec<Vec<i32>>) {
path.push(u);
if u == graph.len() as i32 - 1 {
paths.push(path.clone());
} else {
for &v in &graph[u as usize] {
f(graph, v, path, paths);
}
}
path.pop();
}
let mut path = vec![];
let mut paths = vec![];
f(&graph, 0, &mut path, &mut paths);
paths
}
}
980. Unique Paths III⌗
const DIRS: [[i32; 2]; 4] = [[0, 1], [1, 0], [0, -1], [-1, 0]];
impl Solution {
pub fn unique_paths_iii(mut grid: Vec<Vec<i32>>) -> i32 {
fn f(grid: &mut Vec<Vec<i32>>, i: i32, j: i32, empty: i32) -> i32 {
if i < 0 || i >= grid.len() as i32 || j < 0 || j >= grid[0].len() as i32 {
return 0;
}
let (ui, uj) = (i as usize, j as usize);
if grid[ui][uj] == -1 {
return 0;
}
if grid[ui][uj] == 2 && empty == 0 {
return 1;
}
let mut ret = 0;
let v = grid[ui][uj];
grid[ui][uj] = -1;
for dir in DIRS {
ret += f(grid, i + dir[0], j + dir[1], empty - 1);
}
grid[ui][uj] = v;
ret
}
let mut empty = 0;
let mut si = 0;
let mut sj = 0;
for i in 0..grid.len() {
for j in 0..grid[0].len() {
if grid[i][j] == 1 {
si = i as i32;
sj = j as i32;
}
if grid[i][j] == 0 {
empty += 1;
}
}
}
f(&mut grid, si, sj, empty + 1)
}
}
Read other posts