Compare commits
44 Commits
ba7ac701a7
...
master
Author | SHA1 | Date | |
---|---|---|---|
e6a52152ac
|
|||
6d9aecd427
|
|||
7a5716233b
|
|||
f1d54e2540
|
|||
9c5919af38
|
|||
17c17b126f
|
|||
b200c4032e
|
|||
2ce7e6667f
|
|||
fb6224fc12 | |||
d7f2a5dc1b | |||
f91eaffcb3 | |||
909d89a297 | |||
26bb74425e | |||
1cafc5eca5 | |||
1a9ecb53eb | |||
993535a05b | |||
11ef8edf9d | |||
9f65089c2d | |||
4e6deb7aad | |||
a3d73376bb | |||
f838767e30 | |||
69ff07860e | |||
1907feaa7a | |||
ce641ab871 | |||
90bdc41ca6 | |||
fd2924d216 | |||
7b7d6ca26d | |||
9232c689c4 | |||
ebc48df001 | |||
62515ef741 | |||
b8ba1dd234 | |||
3b7b699f31 | |||
b52d178f9e | |||
8db7360972 | |||
b94d1bc1e7 | |||
706700c639 | |||
0cdca38ad9 | |||
c2b87c5f09 | |||
25f8703b39 | |||
879c2b775e | |||
443c8fff12 | |||
ffa2553a37 | |||
338f74cb9e | |||
5751d9d82e |
@@ -618,3 +618,89 @@ mod p1399_count_largest_group;
|
||||
mod p2338_count_the_number_of_ideal_arrays;
|
||||
|
||||
mod p2845_count_of_interesting_subarrays;
|
||||
|
||||
mod p1287_element_appearing_more_than_25_in_sorted_array;
|
||||
mod p2444_count_subarrays_with_fixed_bounds;
|
||||
|
||||
mod p3392_count_subarrays_of_length_three_with_a_condition;
|
||||
|
||||
mod p2302_count_subarrays_with_score_less_than_k;
|
||||
mod p2962_count_subarrays_where_max_element_appears_at_least_k_times;
|
||||
|
||||
mod p2071_maximum_number_of_tasks_you_can_assign;
|
||||
|
||||
mod p838_push_dominoes;
|
||||
|
||||
mod p1007_minimum_domino_rotations_for_equal_row;
|
||||
|
||||
mod p1128_number_of_equivalent_domino_pairs;
|
||||
|
||||
mod p790_domino_and_tromino_tiling;
|
||||
|
||||
mod p1920_build_array_from_permutation;
|
||||
|
||||
mod p3341_find_minimum_time_to_reach_last_room_i;
|
||||
|
||||
mod p3342_find_minimum_time_to_reach_last_room_ii;
|
||||
|
||||
mod p3343_count_number_of_balanced_permutations;
|
||||
|
||||
mod p2918_minimum_equal_sum_of_two_arrays_after_replacing_zeros;
|
||||
|
||||
mod p1550_three_consecutive_odds;
|
||||
|
||||
mod p2094_finding_3_digit_even_numbers;
|
||||
|
||||
mod p3335_total_characters_in_string_after_transformations_i;
|
||||
|
||||
mod p3337_total_characters_in_string_after_transformations_ii;
|
||||
|
||||
mod p2900_longest_unequal_adjacent_groups_subsequence_i;
|
||||
|
||||
mod p2901_longest_unequal_adjacent_groups_subsequence_ii;
|
||||
|
||||
mod p75_sort_colors;
|
||||
|
||||
mod p1931_painting_a_grid_with_three_different_colors;
|
||||
|
||||
mod p3024_type_of_triangle;
|
||||
|
||||
mod p3355_zero_array_transformation_i;
|
||||
|
||||
mod p3356_zero_array_transformation_ii;
|
||||
|
||||
mod p3362_zero_array_transformation_iii;
|
||||
|
||||
mod p3068_find_the_maximum_sum_of_node_values;
|
||||
|
||||
mod p2942_find_words_containing_character;
|
||||
|
||||
mod p2131_longest_palindrome_by_concatenating_two_letter_words;
|
||||
|
||||
mod p1857_largest_color_value_in_a_directed_graph;
|
||||
|
||||
mod p2894_divisible_and_non_divisible_sums_difference;
|
||||
|
||||
mod p3372_maximize_the_number_of_target_nodes_after_connecting_trees_i;
|
||||
|
||||
mod p3373_maximize_the_number_of_target_nodes_after_connecting_trees_ii;
|
||||
|
||||
mod p2359_find_closest_node_to_given_two_nodes;
|
||||
|
||||
mod p2929_distribute_candies_among_children_ii;
|
||||
|
||||
mod p1298_maximum_candies_you_can_get_from_boxes;
|
||||
|
||||
mod p3403_find_the_lexicographically_largest_string_from_the_box_i;
|
||||
|
||||
mod p1061_lexicographically_smallest_equivalent_string;
|
||||
|
||||
mod p2434_using_a_robot_to_print_the_lexicographically_smallest_string;
|
||||
|
||||
mod p3170_lexicographically_minimum_string_after_removing_stars;
|
||||
|
||||
mod p386_lexicographical_numbers;
|
||||
|
||||
mod p440_k_th_smallest_in_lexicographical_order;
|
||||
|
||||
mod p3442_maximum_difference_between_even_and_odd_frequency_i;
|
||||
|
63
src/problem/p1007_minimum_domino_rotations_for_equal_row.rs
Normal file
63
src/problem/p1007_minimum_domino_rotations_for_equal_row.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* [1007] Minimum Domino Rotations For Equal Row
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn min_domino_rotations(tops: Vec<i32>, bottoms: Vec<i32>) -> i32 {
|
||||
let sequence: Vec<(i32, i32)> = tops.into_iter().zip(bottoms.into_iter()).collect();
|
||||
|
||||
// 应该首先确定相同的值是多少
|
||||
let mut value = 0;
|
||||
if sequence[1..]
|
||||
.iter()
|
||||
.all(|(t, b)| *t == sequence[0].0 || *b == sequence[0].0)
|
||||
{
|
||||
value = sequence[0].0;
|
||||
}
|
||||
if sequence[1..]
|
||||
.iter()
|
||||
.all(|(t, b)| *t == sequence[0].1 || *b == sequence[0].1)
|
||||
{
|
||||
value = sequence[0].1;
|
||||
}
|
||||
|
||||
if value == 0 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sequence
|
||||
.iter()
|
||||
.filter(|(t, b)| *t != value)
|
||||
.count()
|
||||
.min(sequence.iter().filter(|(t, b)| *b != value).count()) as i32
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1007() {
|
||||
assert_eq!(
|
||||
1,
|
||||
Solution::min_domino_rotations(
|
||||
vec![1, 2, 1, 1, 1, 2, 2, 2],
|
||||
vec![2, 1, 2, 2, 2, 2, 2, 2]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
2,
|
||||
Solution::min_domino_rotations(vec![2, 1, 2, 4, 2, 2], vec![5, 2, 6, 2, 3, 2])
|
||||
);
|
||||
assert_eq!(
|
||||
-1,
|
||||
Solution::min_domino_rotations(vec![3, 5, 1, 2, 3], vec![3, 6, 3, 3, 4])
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* [1061] Lexicographically Smallest Equivalent String
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
/// Use union find set for this question
|
||||
struct EquivalentSet {
|
||||
parents: Vec<usize>,
|
||||
min_values: Vec<usize>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for EquivalentSet {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "parents: \n")?;
|
||||
|
||||
for (i, &v) in self.parents.iter().enumerate() {
|
||||
write!(
|
||||
f,
|
||||
"{} -> {}\n",
|
||||
Self::convert_to_char(i),
|
||||
Self::convert_to_char(v)
|
||||
)?;
|
||||
}
|
||||
|
||||
writeln!(f, "min_values:")?;
|
||||
|
||||
for (i, &v) in self.min_values.iter().enumerate() {
|
||||
writeln!(
|
||||
f,
|
||||
"{} -> {}",
|
||||
Self::convert_to_char(i),
|
||||
Self::convert_to_char(v)
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl EquivalentSet {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
// Only lower characters
|
||||
parents: (0..26).collect(),
|
||||
min_values: (0..26).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_to_char(c: usize) -> char {
|
||||
(c as u8 + b'a') as char
|
||||
}
|
||||
|
||||
fn find(&mut self, a: usize) -> (usize, usize) {
|
||||
if self.parents[a] == a {
|
||||
(a, self.min_values[a])
|
||||
} else {
|
||||
let (p, min_value) = self.find(self.parents[a]);
|
||||
self.parents[a] = p;
|
||||
self.min_values[a] = min_value;
|
||||
(p, min_value)
|
||||
}
|
||||
}
|
||||
|
||||
fn merge(&mut self, a: usize, b: usize) {
|
||||
let ((a_p, a_min_value), (b_p, b_min_value)) = (self.find(a), self.find(b));
|
||||
let min_value = a_min_value.min(b_min_value).min(a).min(b);
|
||||
|
||||
self.parents[a_p] = b_p;
|
||||
self.min_values[a_p] = min_value;
|
||||
self.min_values[b_p] = min_value;
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn smallest_equivalent_string(s1: String, s2: String, base_str: String) -> String {
|
||||
let mut set = EquivalentSet::new();
|
||||
|
||||
for (a, b) in s1.bytes().zip(s2.bytes()) {
|
||||
set.merge((a - b'a') as usize, (b - b'a') as usize);
|
||||
}
|
||||
|
||||
String::from_utf8(
|
||||
base_str
|
||||
.bytes()
|
||||
.map(|c| {
|
||||
let (_, min_value) = set.find((c - b'a') as usize);
|
||||
|
||||
min_value as u8 + b'a'
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1061() {
|
||||
assert_eq!(
|
||||
"makkek",
|
||||
Solution::smallest_equivalent_string(
|
||||
"parker".to_string(),
|
||||
"morris".to_string(),
|
||||
"parser".to_string()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
"hdld",
|
||||
Solution::smallest_equivalent_string(
|
||||
"hello".to_string(),
|
||||
"world".to_string(),
|
||||
"hold".to_string()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
"aauaaaaada".to_string(),
|
||||
Solution::smallest_equivalent_string(
|
||||
"leetcode".to_string(),
|
||||
"programs".to_string(),
|
||||
"sourcecode".to_string()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
58
src/problem/p1128_number_of_equivalent_domino_pairs.rs
Normal file
58
src/problem/p1128_number_of_equivalent_domino_pairs.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* [1128] Number of Equivalent Domino Pairs
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::HashMap;
|
||||
|
||||
impl Solution {
|
||||
pub fn num_equiv_domino_pairs(dominoes: Vec<Vec<i32>>) -> i32 {
|
||||
let mut map = HashMap::new();
|
||||
let mut result = 0;
|
||||
|
||||
for card in dominoes.iter() {
|
||||
let sum = card[0] * 10 + card[1];
|
||||
|
||||
if let Some(count) = map.get(&sum) {
|
||||
result += *count;
|
||||
}
|
||||
|
||||
let entry = map.entry(sum).or_insert(0);
|
||||
*entry += 1;
|
||||
|
||||
let reverse_sum = card[1] * 10 + card[0];
|
||||
if reverse_sum != sum {
|
||||
let entry = map.entry(card[1] * 10 + card[0]).or_insert(0);
|
||||
*entry += 1;
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1128() {
|
||||
assert_eq!(
|
||||
1,
|
||||
Solution::num_equiv_domino_pairs(vec![vec![1, 2], vec![2, 1], vec![3, 4], vec![5, 6]])
|
||||
);
|
||||
assert_eq!(
|
||||
3,
|
||||
Solution::num_equiv_domino_pairs(vec![
|
||||
vec![1, 2],
|
||||
vec![1, 2],
|
||||
vec![1, 1],
|
||||
vec![1, 2],
|
||||
vec![2, 2]
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
use std::thread::current;
|
||||
|
||||
/**
|
||||
* [1287] Element Appearing More Than 25% In Sorted Array
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn find_special_integer(arr: Vec<i32>) -> i32 {
|
||||
let mut last = arr[0];
|
||||
let mut count = 1;
|
||||
let threshold = arr.len() / 4;
|
||||
|
||||
for &i in arr[1..].iter() {
|
||||
if last == i {
|
||||
count += 1;
|
||||
} else {
|
||||
last = i;
|
||||
count = 1;
|
||||
}
|
||||
|
||||
if count > threshold {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
last
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1287() {
|
||||
assert_eq!(
|
||||
6,
|
||||
Solution::find_special_integer(vec![1, 2, 2, 6, 6, 6, 6, 7, 10])
|
||||
);
|
||||
assert_eq!(1, Solution::find_special_integer(vec![1, 1]));
|
||||
}
|
||||
}
|
95
src/problem/p1298_maximum_candies_you_can_get_from_boxes.rs
Normal file
95
src/problem/p1298_maximum_candies_you_can_get_from_boxes.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* [1298] Maximum Candies You Can Get from Boxes
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::{HashSet, VecDeque};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
impl Solution {
|
||||
pub fn max_candies(
|
||||
status: Vec<i32>,
|
||||
candies: Vec<i32>,
|
||||
keys: Vec<Vec<i32>>,
|
||||
contained_boxes: Vec<Vec<i32>>,
|
||||
initial_boxes: Vec<i32>,
|
||||
) -> i32 {
|
||||
let mut result = 0;
|
||||
let mut boxes_in_hand: HashSet<usize> =
|
||||
HashSet::from_iter(initial_boxes.into_iter().map(|x| x as usize));
|
||||
let mut can_open_boxes: HashSet<usize> =
|
||||
HashSet::from_iter(status.iter().enumerate().filter_map(|(i, v)| {
|
||||
if *v == 1 {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}));
|
||||
let mut opened_boxes = HashSet::new();
|
||||
let mut queue = VecDeque::new();
|
||||
|
||||
for &b in boxes_in_hand.iter().filter(|x| status[**x] == 1) {
|
||||
queue.push_back(b);
|
||||
opened_boxes.insert(b);
|
||||
result += candies[b];
|
||||
}
|
||||
|
||||
while let Some(b) = queue.pop_front() {
|
||||
for &key in keys[b].iter() {
|
||||
let key = key as usize;
|
||||
can_open_boxes.insert(key);
|
||||
|
||||
if !opened_boxes.contains(&key) && boxes_in_hand.contains(&key) {
|
||||
queue.push_back(key);
|
||||
opened_boxes.insert(key);
|
||||
result += candies[key];
|
||||
}
|
||||
}
|
||||
|
||||
for &new_box in contained_boxes[b].iter() {
|
||||
let new_box = new_box as usize;
|
||||
boxes_in_hand.insert(new_box);
|
||||
|
||||
if !opened_boxes.contains(&new_box) && can_open_boxes.contains(&new_box) {
|
||||
queue.push_back(new_box);
|
||||
opened_boxes.insert(new_box);
|
||||
result += candies[new_box];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1298() {
|
||||
assert_eq!(
|
||||
16,
|
||||
Solution::max_candies(
|
||||
vec![1, 0, 1, 0],
|
||||
vec![7, 5, 4, 1000],
|
||||
vec![vec![], vec![], vec![1], vec![]],
|
||||
vec![vec![1, 2], vec![3], vec![], vec![]],
|
||||
vec![0]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
6,
|
||||
Solution::max_candies(
|
||||
vec![1, 0, 0, 0, 0, 0],
|
||||
vec![1, 1, 1, 1, 1, 1],
|
||||
vec![vec![1, 2, 3, 4, 5], vec![], vec![], vec![], vec![], vec![]],
|
||||
vec![vec![1, 2, 3, 4, 5], vec![], vec![], vec![], vec![], vec![]],
|
||||
vec![0]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
42
src/problem/p1550_three_consecutive_odds.rs
Normal file
42
src/problem/p1550_three_consecutive_odds.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* [1550] Three Consecutive Odds
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn three_consecutive_odds(arr: Vec<i32>) -> bool {
|
||||
if arr.len() < 3 {
|
||||
return false;
|
||||
}
|
||||
|
||||
arr.iter()
|
||||
.enumerate()
|
||||
.skip(2)
|
||||
.filter_map(|(i, &z)| {
|
||||
if arr[i - 2] % 2 == 1 && arr[i - 1] % 2 == 1 && z % 2 == 1 {
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.next()
|
||||
.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1550() {
|
||||
assert!(!Solution::three_consecutive_odds(vec![2, 6, 4, 1]));
|
||||
assert!(Solution::three_consecutive_odds(vec![
|
||||
1, 2, 34, 3, 4, 5, 7, 23, 12
|
||||
]));
|
||||
}
|
||||
}
|
98
src/problem/p1857_largest_color_value_in_a_directed_graph.rs
Normal file
98
src/problem/p1857_largest_color_value_in_a_directed_graph.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* [1857] Largest Color Value in a Directed Graph
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
impl Solution {
|
||||
pub fn largest_path_value(colors: String, edges: Vec<Vec<i32>>) -> i32 {
|
||||
let colors: Vec<usize> = colors.bytes().map(|x| (x - b'a') as usize).collect();
|
||||
let mut adjacency_matrix = vec![vec![]; colors.len()];
|
||||
// 入度节点
|
||||
let mut in_degrees = vec![0; colors.len()];
|
||||
|
||||
for edge in edges.iter() {
|
||||
let start = edge[0] as usize;
|
||||
let end = edge[1] as usize;
|
||||
|
||||
adjacency_matrix[start].push(end);
|
||||
in_degrees[end] += 1;
|
||||
}
|
||||
|
||||
// 使用拓扑排序判断是否有环
|
||||
// 同时获得一个拓扑序列表
|
||||
let mut queue = VecDeque::from_iter(in_degrees.iter().enumerate().filter_map(|(i, v)| {
|
||||
if *v == 0 {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}));
|
||||
let mut topology_list = vec![];
|
||||
|
||||
while let Some(head) = queue.pop_front() {
|
||||
topology_list.push(head);
|
||||
for &next in adjacency_matrix[head].iter() {
|
||||
in_degrees[next] -= 1;
|
||||
|
||||
if in_degrees[next] == 0 {
|
||||
queue.push_back(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if in_degrees.iter().any(|x| *x != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// dp[i][c]表示从节点i开始路径上颜色为c的计数
|
||||
// 颜色只能是小写字母
|
||||
let mut dp = vec![vec![0; 26]; topology_list.len()];
|
||||
let mut result = HashMap::new();
|
||||
|
||||
for &node in topology_list.iter().rev() {
|
||||
let c = colors[node];
|
||||
|
||||
for &next in adjacency_matrix[node].iter() {
|
||||
for i in 0..26 {
|
||||
dp[node][i] = dp[node][i].max(dp[next][i]);
|
||||
}
|
||||
|
||||
dp[node][c] = dp[node][c].max(dp[next][c] + 1);
|
||||
let entry = result.entry(c).or_insert(0);
|
||||
*entry = dp[node][c].max(*entry);
|
||||
}
|
||||
|
||||
if adjacency_matrix[node].is_empty() {
|
||||
dp[node][c] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
result.values().max().map_or_else(|| 1, |x| *x)
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1857() {
|
||||
assert_eq!(
|
||||
3,
|
||||
Solution::largest_path_value(
|
||||
"abaca".to_string(),
|
||||
vec![vec![0, 1], vec![0, 2], vec![2, 3], vec![3, 4]]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
-1,
|
||||
Solution::largest_path_value("a".to_string(), vec![vec![0, 0]])
|
||||
);
|
||||
}
|
||||
}
|
31
src/problem/p1920_build_array_from_permutation.rs
Normal file
31
src/problem/p1920_build_array_from_permutation.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* [1920] Build Array from Permutation
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn build_array(nums: Vec<i32>) -> Vec<i32> {
|
||||
nums.iter().map(|x| nums[*x as usize]).collect()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1920() {
|
||||
assert_eq!(
|
||||
vec![0, 1, 2, 4, 5, 3],
|
||||
Solution::build_array(vec![0, 2, 1, 5, 3, 4])
|
||||
);
|
||||
assert_eq!(
|
||||
vec![4, 5, 0, 1, 2, 3],
|
||||
Solution::build_array(vec![5, 0, 1, 2, 3, 4])
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* [1931] Painting a Grid With Three Different Colors
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::HashMap;
|
||||
|
||||
const MOD: i32 = 1_000_000_007;
|
||||
|
||||
impl Solution {
|
||||
pub fn color_the_grid(m: i32, n: i32) -> i32 {
|
||||
let mut mask_count = 3_usize.pow(m as u32);
|
||||
// 存储一行的所有合法涂色方式
|
||||
// key表示mask
|
||||
// value表示实际的涂色数组
|
||||
let mut valid_masks = HashMap::new();
|
||||
|
||||
for mask in 0..mask_count {
|
||||
let mut color = vec![];
|
||||
let mut m_mask = mask;
|
||||
|
||||
for _ in 0..m {
|
||||
color.push(m_mask % 3);
|
||||
m_mask = m_mask / 3;
|
||||
}
|
||||
|
||||
if color.iter().skip(1).zip(color.iter()).all(|(x, y)| x != y) {
|
||||
valid_masks.insert(mask, color);
|
||||
}
|
||||
}
|
||||
|
||||
// 预处理相邻行的合法表示
|
||||
let mut adjacent_valid_masks = HashMap::new();
|
||||
|
||||
for (&mask1, color1) in valid_masks.iter() {
|
||||
for (&mask2, color2) in valid_masks.iter() {
|
||||
if color1.iter().zip(color2.iter()).all(|(x, y)| x != y) {
|
||||
let entry = adjacent_valid_masks.entry(mask1).or_insert(vec![]);
|
||||
entry.push(mask2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动的DP数组
|
||||
let mut dp = vec![0; mask_count];
|
||||
|
||||
// 初始化为第一行
|
||||
for &mask in valid_masks.keys() {
|
||||
dp[mask] = 1;
|
||||
}
|
||||
|
||||
for _ in 1..n {
|
||||
let mut next_dp = vec![0; mask_count];
|
||||
|
||||
for &next_mask in valid_masks.keys() {
|
||||
for &mask in adjacent_valid_masks.get(&next_mask).unwrap() {
|
||||
next_dp[next_mask] += dp[mask];
|
||||
|
||||
if next_dp[next_mask] >= MOD {
|
||||
next_dp[next_mask] -= MOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dp = next_dp;
|
||||
}
|
||||
|
||||
dp.into_iter().fold(0, |sum, i| {
|
||||
if sum + i >= MOD {
|
||||
sum + i - MOD
|
||||
} else {
|
||||
sum + i
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1931() {
|
||||
assert_eq!(3, Solution::color_the_grid(1, 1));
|
||||
assert_eq!(6, Solution::color_the_grid(1, 2));
|
||||
assert_eq!(580986, Solution::color_the_grid(5, 5));
|
||||
}
|
||||
}
|
108
src/problem/p2071_maximum_number_of_tasks_you_can_assign.rs
Normal file
108
src/problem/p2071_maximum_number_of_tasks_you_can_assign.rs
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* [2071] Maximum Number of Tasks You Can Assign
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::VecDeque;
|
||||
|
||||
impl Solution {
|
||||
pub fn max_task_assign(
|
||||
mut tasks: Vec<i32>,
|
||||
mut workers: Vec<i32>,
|
||||
pills: i32,
|
||||
strength: i32,
|
||||
) -> i32 {
|
||||
let (n, m) = (tasks.len(), workers.len());
|
||||
|
||||
tasks.sort_unstable();
|
||||
workers.sort_unstable();
|
||||
|
||||
let check = |middle: usize| -> bool {
|
||||
// 注意middle的溢出问题
|
||||
if middle < 1 {
|
||||
return true;
|
||||
}
|
||||
|
||||
let mut p = pills;
|
||||
let mut worker_queue = VecDeque::new();
|
||||
let mut ptr = m - 1;
|
||||
|
||||
for i in (0..=middle - 1).rev() {
|
||||
while ptr >= m - middle && workers[ptr] + strength >= tasks[i] {
|
||||
worker_queue.push_front(workers[ptr]);
|
||||
|
||||
if ptr == 0 {
|
||||
break;
|
||||
}
|
||||
ptr -= 1;
|
||||
}
|
||||
|
||||
if worker_queue.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let last = worker_queue.back().unwrap();
|
||||
|
||||
if *last >= tasks[i] {
|
||||
worker_queue.pop_back();
|
||||
} else {
|
||||
if p == 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
p -= 1;
|
||||
worker_queue.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
let (mut left, mut right) = (1, m.min(n));
|
||||
let mut result = 0;
|
||||
|
||||
while left <= right {
|
||||
let middle = (left + right) / 2;
|
||||
if check(middle) {
|
||||
result = middle;
|
||||
left = middle + 1;
|
||||
} else {
|
||||
right = middle - 1;
|
||||
}
|
||||
}
|
||||
|
||||
result as i32
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2071() {
|
||||
assert_eq!(
|
||||
1,
|
||||
Solution::max_task_assign(vec![35], vec![83, 20, 4, 66], 3, 41)
|
||||
);
|
||||
assert_eq!(
|
||||
3,
|
||||
Solution::max_task_assign(vec![3, 2, 1], vec![0, 3, 3], 1, 1)
|
||||
);
|
||||
assert_eq!(
|
||||
1,
|
||||
Solution::max_task_assign(vec![5, 4], vec![0, 0, 0], 1, 5)
|
||||
);
|
||||
assert_eq!(
|
||||
2,
|
||||
Solution::max_task_assign(vec![10, 15, 30], vec![0, 10, 10, 10, 10], 3, 10)
|
||||
);
|
||||
assert_eq!(
|
||||
3,
|
||||
Solution::max_task_assign(vec![5, 9, 8, 5, 9], vec![1, 6, 4, 2, 6], 1, 5)
|
||||
);
|
||||
}
|
||||
}
|
64
src/problem/p2094_finding_3_digit_even_numbers.rs
Normal file
64
src/problem/p2094_finding_3_digit_even_numbers.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* [2094] Finding 3-Digit Even Numbers
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::HashSet;
|
||||
|
||||
impl Solution {
|
||||
pub fn find_even_numbers(digits: Vec<i32>) -> Vec<i32> {
|
||||
let mut result = HashSet::new();
|
||||
|
||||
for (x, first) in
|
||||
digits
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, &x)| if x != 0 { Some((i, x)) } else { None })
|
||||
{
|
||||
for (y, second) in
|
||||
digits
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, &y)| if i != x { Some((i, y)) } else { None })
|
||||
{
|
||||
for third in digits.iter().enumerate().filter_map(|(i, &z)| {
|
||||
if i != x && i != y && z % 2 == 0 {
|
||||
Some(z)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
result.insert(first * 100 + second * 10 + third);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut result: Vec<i32> = result.into_iter().collect();
|
||||
result.sort_unstable();
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2094() {
|
||||
assert_eq!(
|
||||
vec![102, 120, 130, 132, 210, 230, 302, 310, 312, 320],
|
||||
Solution::find_even_numbers(vec![2, 1, 3, 0])
|
||||
);
|
||||
assert_eq!(
|
||||
vec![222, 228, 282, 288, 822, 828, 882],
|
||||
Solution::find_even_numbers(vec![2, 2, 8, 8, 2])
|
||||
);
|
||||
assert_eq!(
|
||||
Vec::<i32>::new(),
|
||||
Solution::find_even_numbers(vec![3, 7, 5])
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* [2131] Longest Palindrome by Concatenating Two Letter Words
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::HashMap;
|
||||
|
||||
impl Solution {
|
||||
pub fn longest_palindrome(words: Vec<String>) -> i32 {
|
||||
let mut counter = HashMap::new();
|
||||
let mut same_counter = HashMap::new();
|
||||
|
||||
for word in words.iter() {
|
||||
let mut chars = word.bytes();
|
||||
let first = (chars.next().unwrap() - b'a') as i32;
|
||||
let second = (chars.next().unwrap() - b'a') as i32;
|
||||
|
||||
if first < second {
|
||||
let hash = first * 26 + second;
|
||||
let entry = counter.entry(hash).or_insert((0, 0));
|
||||
entry.0 += 1;
|
||||
} else if first > second {
|
||||
let hash = second * 26 + first;
|
||||
let entry = counter.entry(hash).or_insert((0, 0));
|
||||
entry.1 += 1;
|
||||
} else {
|
||||
let entry = same_counter.entry(first).or_insert(0);
|
||||
*entry += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 对于两个不同的字符
|
||||
// 取计数的最小值
|
||||
let mut result: i32 = counter
|
||||
.values()
|
||||
.filter_map(|&(x, y)| Some(x.min(y) * 4))
|
||||
.sum();
|
||||
|
||||
// 对于两个相同的字符
|
||||
// 如果成对就可以加入答案
|
||||
result += same_counter
|
||||
.values()
|
||||
.filter_map(|&v| Some(v / 2 * 4))
|
||||
.sum::<i32>();
|
||||
|
||||
// 再判断是否有落单的相同字符放在中间
|
||||
// 注意只能放一次
|
||||
result += same_counter
|
||||
.values()
|
||||
.filter_map(|&v| if v % 2 != 0 { Some(()) } else { None })
|
||||
.next()
|
||||
.map_or(0, |()| 2);
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2131() {
|
||||
assert_eq!(
|
||||
6,
|
||||
Solution::longest_palindrome(vec_string!("aa", "aa", "aa"))
|
||||
);
|
||||
assert_eq!(
|
||||
6,
|
||||
Solution::longest_palindrome(vec_string!["lc", "cl", "gg"])
|
||||
);
|
||||
assert_eq!(
|
||||
8,
|
||||
Solution::longest_palindrome(vec_string!["ab", "ty", "yt", "lc", "cl", "ab"])
|
||||
);
|
||||
assert_eq!(
|
||||
2,
|
||||
Solution::longest_palindrome(vec_string!["ll", "cc", "xx"])
|
||||
);
|
||||
}
|
||||
}
|
48
src/problem/p2302_count_subarrays_with_score_less_than_k.rs
Normal file
48
src/problem/p2302_count_subarrays_with_score_less_than_k.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* [2302] Count Subarrays With Score Less Than K
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn count_subarrays(nums: Vec<i32>, k: i64) -> i64 {
|
||||
let n = nums.len();
|
||||
|
||||
let (mut result, mut total_sum) = (0, 0);
|
||||
let mut left = 0;
|
||||
|
||||
for right in 0..n {
|
||||
total_sum += nums[right] as i64;
|
||||
|
||||
while left <= right && total_sum * ((right - left + 1) as i64) >= k {
|
||||
total_sum -= nums[left] as i64;
|
||||
left += 1;
|
||||
}
|
||||
|
||||
result += (right as i64 - left as i64) + 1;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2302() {
|
||||
assert_eq!(
|
||||
3,
|
||||
Solution::count_subarrays(
|
||||
vec![9, 5, 3, 8, 4, 7, 2, 7, 4, 5, 4, 9, 1, 4, 8, 10, 8, 4, 7],
|
||||
4
|
||||
)
|
||||
);
|
||||
assert_eq!(6, Solution::count_subarrays(vec![2, 1, 4, 3, 5], 10));
|
||||
assert_eq!(5, Solution::count_subarrays(vec![1, 1, 1], 5));
|
||||
}
|
||||
}
|
73
src/problem/p2359_find_closest_node_to_given_two_nodes.rs
Normal file
73
src/problem/p2359_find_closest_node_to_given_two_nodes.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
/**
|
||||
* [2359] Find Closest Node to Given Two Nodes
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::{HashSet, VecDeque};
|
||||
|
||||
impl Solution {
|
||||
pub fn closest_meeting_node(edges: Vec<i32>, node1: i32, node2: i32) -> i32 {
|
||||
let edges: Vec<Option<usize>> = edges.into_iter().map(|x| x.try_into().ok()).collect();
|
||||
|
||||
let distances1 = Self::search_distances(&edges, node1 as usize);
|
||||
let distances2 = Self::search_distances(&edges, node2 as usize);
|
||||
|
||||
let mut result: Option<(usize, i32)> = None;
|
||||
|
||||
for i in 0..edges.len() {
|
||||
if distances1[i] == i32::MAX || distances2[i] == i32::MAX {
|
||||
continue;
|
||||
}
|
||||
|
||||
let distance = distances1[i].max(distances2[i]);
|
||||
|
||||
if let Some((pos, d)) = result {
|
||||
if distance < d {
|
||||
result = Some((i, distance));
|
||||
}
|
||||
} else {
|
||||
result = Some((i, distance));
|
||||
}
|
||||
}
|
||||
|
||||
result.map_or(-1, |x| x.0 as i32)
|
||||
}
|
||||
|
||||
fn search_distances(edges: &Vec<Option<usize>>, node: usize) -> Vec<i32> {
|
||||
let mut distances = vec![i32::MAX; edges.len()];
|
||||
let mut queue = VecDeque::new();
|
||||
let mut visited = HashSet::new();
|
||||
|
||||
queue.push_back((node, 0));
|
||||
|
||||
while let Some((pos, d)) = queue.pop_front() {
|
||||
if !visited.insert(pos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
distances[pos] = d;
|
||||
|
||||
if let Some(next) = edges[pos] {
|
||||
queue.push_back((next, d + 1));
|
||||
}
|
||||
}
|
||||
|
||||
distances
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2359() {
|
||||
assert_eq!(2, Solution::closest_meeting_node(vec![2, 2, 3, -1], 0, 1));
|
||||
assert_eq!(2, Solution::closest_meeting_node(vec![1, 2, -1], 0, 2));
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* [2434] Using a Robot to Print the Lexicographically Smallest String
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::HashMap;
|
||||
|
||||
impl Solution {
|
||||
pub fn robot_with_string(s: String) -> String {
|
||||
let s: Vec<u8> = s.bytes().collect();
|
||||
let mut character_map = HashMap::new();
|
||||
|
||||
for &c in s.iter() {
|
||||
let entry = character_map.entry(c).or_insert(0);
|
||||
*entry += 1;
|
||||
}
|
||||
|
||||
// The Minimal value in the s.
|
||||
let mut min_character = b'a';
|
||||
let mut result = Vec::with_capacity(s.len());
|
||||
let mut buffer = Vec::with_capacity(s.len());
|
||||
|
||||
for &c in s.iter() {
|
||||
buffer.push(c);
|
||||
*character_map.get_mut(&c).unwrap() -= 1;
|
||||
|
||||
// Find the minimal value in the s.
|
||||
while min_character != b'z' && character_map.get(&min_character).is_none_or(|x| *x == 0)
|
||||
{
|
||||
min_character += 1;
|
||||
}
|
||||
|
||||
while let Some(&head) = buffer.last() {
|
||||
if head <= min_character {
|
||||
result.push(head);
|
||||
buffer.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String::from_utf8(result).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2434() {
|
||||
assert_eq!("azz", Solution::robot_with_string("zza".to_string()));
|
||||
assert_eq!("abc", Solution::robot_with_string("bac".to_string()));
|
||||
}
|
||||
}
|
56
src/problem/p2444_count_subarrays_with_fixed_bounds.rs
Normal file
56
src/problem/p2444_count_subarrays_with_fixed_bounds.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* [2444] Count Subarrays With Fixed Bounds
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn count_subarrays(nums: Vec<i32>, min_k: i32, max_k: i32) -> i64 {
|
||||
let mut result = 0;
|
||||
let (mut border, mut last_min, mut last_max) = (None, None, None);
|
||||
|
||||
for i in 0..nums.len() {
|
||||
if nums[i] < min_k || nums[i] > max_k {
|
||||
last_max = None;
|
||||
last_min = None;
|
||||
border = Some(i);
|
||||
}
|
||||
|
||||
if nums[i] == min_k {
|
||||
last_min = Some(i);
|
||||
}
|
||||
|
||||
if nums[i] == max_k {
|
||||
last_max = Some(i);
|
||||
}
|
||||
|
||||
if let Some(last_min) = last_min {
|
||||
if let Some(last_max) = last_max {
|
||||
let current = if let Some(border) = border {
|
||||
last_min.min(last_max) - border
|
||||
} else {
|
||||
last_min.min(last_max) + 1
|
||||
};
|
||||
|
||||
result += current as i64
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2444() {
|
||||
assert_eq!(2, Solution::count_subarrays(vec![1, 3, 5, 2, 7, 5], 1, 5));
|
||||
assert_eq!(10, Solution::count_subarrays(vec![1, 1, 1, 1], 1, 1));
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* [2894] Divisible and Non-divisible Sums Difference
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn difference_of_sums(n: i32, m: i32) -> i32 {
|
||||
(1..=n)
|
||||
.filter_map(|x| if x % m != 0 { Some(x) } else { None })
|
||||
.sum::<i32>()
|
||||
- (1..=n)
|
||||
.filter_map(|x| if x % m == 0 { Some(x) } else { None })
|
||||
.sum::<i32>()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2894() {
|
||||
assert_eq!(19, Solution::difference_of_sums(10, 3));
|
||||
assert_eq!(15, Solution::difference_of_sums(5, 6));
|
||||
assert_eq!(-15, Solution::difference_of_sums(5, 1));
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* [2900] Longest Unequal Adjacent Groups Subsequence I
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn get_longest_subsequence(words: Vec<String>, groups: Vec<i32>) -> Vec<String> {
|
||||
let mut result = vec![words[0].clone()];
|
||||
|
||||
let mut last_number = groups[0];
|
||||
|
||||
for i in 1..groups.len() {
|
||||
if groups[i] != last_number {
|
||||
result.push(words[i].clone());
|
||||
}
|
||||
|
||||
last_number = groups[i];
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2900() {
|
||||
assert_eq!(
|
||||
vec_string!("e", "b"),
|
||||
Solution::get_longest_subsequence(vec_string!("e", "a", "b"), vec![0, 0, 1])
|
||||
);
|
||||
assert_eq!(
|
||||
vec_string!("a", "b", "c"),
|
||||
Solution::get_longest_subsequence(vec_string!("a", "b", "c", "d"), vec![1, 0, 1, 1])
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* [2901] Longest Unequal Adjacent Groups Subsequence II
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn get_words_in_longest_subsequence(words: Vec<String>, groups: Vec<i32>) -> Vec<String> {
|
||||
let n = words.len();
|
||||
let mut dp = vec![1; n];
|
||||
let mut next_pos = vec![None; n];
|
||||
|
||||
for i in 1..n {
|
||||
for j in 0..i {
|
||||
if groups[i] == groups[j] {
|
||||
continue;
|
||||
}
|
||||
|
||||
if words[i].len() != words[j].len() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if Self::calculate_hamming_distance(words[i].as_str(), words[j].as_str()) != 1 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if dp[j] + 1 > dp[i] {
|
||||
dp[i] = dp[j] + 1;
|
||||
next_pos[i] = Some(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let max_pos = dp.iter().enumerate().max_by_key(|x| x.1).unwrap();
|
||||
let mut pos = max_pos.0;
|
||||
|
||||
let mut result = vec![words[pos].clone()];
|
||||
while let Some(p) = next_pos[pos] {
|
||||
result.push(words[p].clone());
|
||||
pos = p;
|
||||
}
|
||||
|
||||
result.into_iter().rev().collect()
|
||||
}
|
||||
|
||||
// 计算字符串之间的汉明距
|
||||
// 两个字符串需要等长
|
||||
fn calculate_hamming_distance(a: &str, b: &str) -> usize {
|
||||
a.bytes()
|
||||
.zip(b.bytes())
|
||||
.filter_map(|(x, y)| if x == y { None } else { Some(()) })
|
||||
.count()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2901() {
|
||||
assert_eq!(
|
||||
vec_string!("dc", "dd", "da"),
|
||||
Solution::get_words_in_longest_subsequence(
|
||||
vec_string!("bad", "dc", "bc", "ccd", "dd", "da", "cad", "dba", "aba"),
|
||||
vec![9, 7, 1, 2, 6, 8, 3, 7, 2]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
vec_string!("bab", "cab"),
|
||||
Solution::get_words_in_longest_subsequence(
|
||||
vec_string!("bab", "dab", "cab"),
|
||||
vec![1, 2, 2]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
vec_string!("a", "b", "c", "d"),
|
||||
Solution::get_words_in_longest_subsequence(
|
||||
vec_string!("a", "b", "c", "d"),
|
||||
vec![1, 2, 3, 4]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* [2918] Minimum Equal Sum of Two Arrays After Replacing Zeros
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::cmp::Ordering;
|
||||
|
||||
impl Solution {
|
||||
pub fn min_sum(nums1: Vec<i32>, nums2: Vec<i32>) -> i64 {
|
||||
let mut nums1_sum: i64 = nums1.iter().map(|x| *x as i64).sum();
|
||||
let mut nums2_sum: i64 = nums2.iter().map(|x| *x as i64).sum();
|
||||
let nums1_zero_count = nums1.iter().filter(|x| **x == 0).count() as i64;
|
||||
let nums2_zero_count = nums2.iter().filter(|x| **x == 0).count() as i64;
|
||||
|
||||
match (nums1_sum + nums1_zero_count).cmp(&(nums2_sum + nums2_zero_count)) {
|
||||
Ordering::Less => {
|
||||
if nums1_zero_count == 0 {
|
||||
-1
|
||||
} else {
|
||||
nums2_sum + nums2_zero_count
|
||||
}
|
||||
}
|
||||
Ordering::Greater => {
|
||||
if nums2_zero_count == 0 {
|
||||
-1
|
||||
} else {
|
||||
nums1_sum + nums1_zero_count
|
||||
}
|
||||
}
|
||||
Ordering::Equal => nums1_sum + nums1_zero_count,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2918() {
|
||||
assert_eq!(12, Solution::min_sum(vec![3, 2, 0, 1, 0], vec![6, 5, 0]));
|
||||
assert_eq!(-1, Solution::min_sum(vec![2, 0, 2, 0], vec![1, 4]));
|
||||
}
|
||||
}
|
31
src/problem/p2929_distribute_candies_among_children_ii.rs
Normal file
31
src/problem/p2929_distribute_candies_among_children_ii.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* [2929] Distribute Candies Among Children II
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn distribute_candies(n: i32, limit: i32) -> i64 {
|
||||
// 0 <= i <= min(n, limit)
|
||||
// 0 <= j <= min(n, limit)
|
||||
// 0 <= n - i - j <= min(n, limit) -> i + j <= n
|
||||
let (n, limit) = (n as i64, limit as i64);
|
||||
(0..=n.min(limit))
|
||||
.map(|i| (limit.min(n - i) - (n - limit - i).max(0) + 1).max(0))
|
||||
.sum()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2929() {
|
||||
assert_eq!(3, Solution::distribute_candies(5, 2));
|
||||
assert_eq!(10, Solution::distribute_candies(3, 3));
|
||||
}
|
||||
}
|
39
src/problem/p2942_find_words_containing_character.rs
Normal file
39
src/problem/p2942_find_words_containing_character.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* [2942] Find Words Containing Character
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn find_words_containing(words: Vec<String>, x: char) -> Vec<i32> {
|
||||
words
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, v)| if v.contains(x) { Some(i as i32) } else { None })
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2942() {
|
||||
assert_eq!(
|
||||
vec![0, 1],
|
||||
Solution::find_words_containing(vec_string!("leet", "code"), 'e')
|
||||
);
|
||||
assert_eq!(
|
||||
vec![0, 2],
|
||||
Solution::find_words_containing(vec_string!("abc", "bcd", "aaaa", "cbc"), 'a')
|
||||
);
|
||||
assert_eq!(
|
||||
Vec::<i32>::new(),
|
||||
Solution::find_words_containing(vec_string!("abc", "bcd", "aaaa", "cbc"), 'z'),
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* [2962] Count Subarrays Where Max Element Appears at Least K Times
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn count_subarrays(nums: Vec<i32>, k: i32) -> i64 {
|
||||
let max = *nums.iter().max().unwrap();
|
||||
let n = nums.len();
|
||||
|
||||
let mut result = 0;
|
||||
let mut count = 0;
|
||||
let mut left = 0;
|
||||
|
||||
for right in 0..n {
|
||||
count += if nums[right] == max { 1 } else { 0 };
|
||||
|
||||
if count >= k {
|
||||
result += (n - right) as i64;
|
||||
}
|
||||
|
||||
while left <= right && count >= k {
|
||||
count -= if nums[left] == max { 1 } else { 0 };
|
||||
|
||||
if count >= k {
|
||||
result += (n - right) as i64;
|
||||
}
|
||||
left += 1;
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_2962() {
|
||||
assert_eq!(6, Solution::count_subarrays(vec![1, 3, 2, 3, 3], 2));
|
||||
assert_eq!(0, Solution::count_subarrays(vec![1, 4, 2, 1], 3));
|
||||
}
|
||||
}
|
40
src/problem/p3024_type_of_triangle.rs
Normal file
40
src/problem/p3024_type_of_triangle.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* [3024] Type of Triangle
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn triangle_type(nums: Vec<i32>) -> String {
|
||||
if nums[0] + nums[1] <= nums[2]
|
||||
|| nums[0] + nums[2] <= nums[1]
|
||||
|| nums[1] + nums[2] <= nums[0]
|
||||
{
|
||||
return "none".to_string();
|
||||
}
|
||||
|
||||
if nums[0] == nums[1] || nums[0] == nums[2] || nums[1] == nums[2] {
|
||||
if nums[0] == nums[1] && nums[1] == nums[2] {
|
||||
"equilateral".to_string()
|
||||
} else {
|
||||
"isosceles".to_string()
|
||||
}
|
||||
} else {
|
||||
"scalene".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3024() {
|
||||
assert_eq!("equilateral", Solution::triangle_type(vec![3, 3, 3]));
|
||||
assert_eq!("scalene", Solution::triangle_type(vec![3, 4, 5]));
|
||||
}
|
||||
}
|
53
src/problem/p3068_find_the_maximum_sum_of_node_values.rs
Normal file
53
src/problem/p3068_find_the_maximum_sum_of_node_values.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* [3068] Find the Maximum Sum of Node Values
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn maximum_value_sum(nums: Vec<i32>, k: i32, _: Vec<Vec<i32>>) -> i64 {
|
||||
let mut result: i64 = nums.iter().map(|x| *x as i64).sum();
|
||||
|
||||
let mut difference: Vec<i64> = nums.iter().map(|&x| ((x ^ k) - x) as i64).collect();
|
||||
difference.sort_unstable_by(|a, b| b.cmp(a));
|
||||
|
||||
for pair in difference.chunks(2) {
|
||||
let sum: i64 = pair.iter().sum();
|
||||
if pair.len() != 2 || sum < 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
result += sum;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3068() {
|
||||
assert_eq!(
|
||||
6,
|
||||
Solution::maximum_value_sum(vec![1, 2, 1], 3, vec![vec![0, 1], vec![0, 2]])
|
||||
);
|
||||
assert_eq!(
|
||||
9,
|
||||
Solution::maximum_value_sum(vec![2, 3], 7, vec![vec![0, 1]])
|
||||
);
|
||||
assert_eq!(
|
||||
42,
|
||||
Solution::maximum_value_sum(
|
||||
vec![7; 6],
|
||||
3,
|
||||
vec![vec![0, 1], vec![0, 2], vec![0, 3], vec![0, 4], vec![0, 5]]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* [3170] Lexicographically Minimum String After Removing Stars
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
struct CharacterPos {
|
||||
char: u8,
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
impl Ord for CharacterPos {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
match other.char.cmp(&self.char) {
|
||||
Ordering::Equal => self.pos.cmp(&other.pos),
|
||||
Ordering::Greater => Ordering::Greater,
|
||||
Ordering::Less => Ordering::Less,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for CharacterPos {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn clear_stars(s: String) -> String {
|
||||
// Use the binary head to store the minimal and nearest character.
|
||||
let mut heap = BinaryHeap::new();
|
||||
// The array stores the tuple (character, is_removed).
|
||||
let mut buffer: Vec<(u8, bool)> = s.bytes().map(|x| (x, false)).collect();
|
||||
|
||||
for (i, v) in s.bytes().enumerate() {
|
||||
if v != b'*' {
|
||||
heap.push(CharacterPos { char: v, pos: i });
|
||||
} else {
|
||||
// Remove the star character firstly.
|
||||
buffer.get_mut(i).unwrap().1 = true;
|
||||
|
||||
// Then find the nearest and minimal character.
|
||||
let head = heap.pop().unwrap();
|
||||
buffer.get_mut(head.pos).unwrap().1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
String::from_utf8(
|
||||
buffer
|
||||
.into_iter()
|
||||
.filter_map(|(c, f)| if f { None } else { Some(c) })
|
||||
.collect(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3170() {
|
||||
assert_eq!("aab", Solution::clear_stars("aaba*".to_string()));
|
||||
assert_eq!("abc", Solution::clear_stars("abc".to_string()));
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* [3335] Total Characters in String After Transformations I
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
const MOD: i32 = 1_000_000_007;
|
||||
|
||||
impl Solution {
|
||||
pub fn length_after_transformations(s: String, t: i32) -> i32 {
|
||||
let mut map = vec![0; 26];
|
||||
|
||||
for c in s.bytes() {
|
||||
map[(c - b'a') as usize] += 1;
|
||||
}
|
||||
|
||||
let mut result = s.bytes().len() as i32;
|
||||
|
||||
for _ in 0..t {
|
||||
let z_count = map[25];
|
||||
|
||||
for c in (0..25).rev() {
|
||||
if map[c] != 0 {
|
||||
map[c + 1] = (map[c + 1] + map[c]) % MOD;
|
||||
map[c] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if z_count != 0 {
|
||||
map[0] = (map[0] + z_count) % MOD;
|
||||
map[1] = (map[1] + z_count) % MOD;
|
||||
result = (result + z_count) % MOD;
|
||||
|
||||
map[25] = (map[25] + MOD - z_count) % MOD;
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3335() {
|
||||
assert_eq!(
|
||||
7,
|
||||
Solution::length_after_transformations("abcyy".to_string(), 2)
|
||||
);
|
||||
assert_eq!(
|
||||
5,
|
||||
Solution::length_after_transformations("azbk".to_string(), 1)
|
||||
);
|
||||
assert_eq!(
|
||||
79033769,
|
||||
Solution::length_after_transformations("jqktcurgdvlibczdsvnsg".to_string(), 7517)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* [3337] Total Characters in String After Transformations II
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::ops::Mul;
|
||||
|
||||
const LENGTH: usize = 26;
|
||||
const MOD: i64 = 1_000_000_007;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct Matrix {
|
||||
array: [[i64; LENGTH]; LENGTH],
|
||||
}
|
||||
|
||||
impl Matrix {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
array: [[0; LENGTH]; LENGTH],
|
||||
}
|
||||
}
|
||||
|
||||
fn unit_matrix() -> Self {
|
||||
let mut matrix = Self::new();
|
||||
|
||||
for i in 0..LENGTH {
|
||||
matrix.array[i][i] = 1;
|
||||
}
|
||||
|
||||
matrix
|
||||
}
|
||||
|
||||
fn quick_multiply(&self, mut y: i64) -> Self {
|
||||
let mut result = Self::unit_matrix();
|
||||
let mut current = self.clone();
|
||||
|
||||
while y > 0 {
|
||||
if y & 1 == 1 {
|
||||
result = result * current;
|
||||
}
|
||||
|
||||
current = current * current;
|
||||
y >>= 1;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul for Matrix {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
let mut result = Self::new();
|
||||
|
||||
for i in 0..LENGTH {
|
||||
for j in 0..LENGTH {
|
||||
for k in 0..LENGTH {
|
||||
result.array[i][j] =
|
||||
(result.array[i][j] + self.array[i][k] * rhs.array[k][j]) % MOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn length_after_transformations(s: String, t: i32, nums: Vec<i32>) -> i32 {
|
||||
let mut t_matrix = Matrix::new();
|
||||
|
||||
for i in 0..LENGTH {
|
||||
for j in 1..=nums[i] {
|
||||
let j = j as usize;
|
||||
t_matrix.array[(i + j) % LENGTH][i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
let transfer_matrix = t_matrix.quick_multiply(t as i64);
|
||||
let mut result = 0;
|
||||
let mut chars = [0; LENGTH];
|
||||
|
||||
for c in s.bytes() {
|
||||
chars[(c - b'a') as usize] += 1;
|
||||
}
|
||||
|
||||
for i in 0..LENGTH {
|
||||
for j in 0..LENGTH {
|
||||
result = (result + transfer_matrix.array[i][j] * chars[j]) % MOD;
|
||||
}
|
||||
}
|
||||
|
||||
result as i32
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3337() {
|
||||
assert_eq!(
|
||||
5,
|
||||
Solution::length_after_transformations(
|
||||
"abcyy".to_owned(),
|
||||
1,
|
||||
vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
7,
|
||||
Solution::length_after_transformations(
|
||||
"abcyy".to_owned(),
|
||||
2,
|
||||
vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
8,
|
||||
Solution::length_after_transformations(
|
||||
"azbk".to_string(),
|
||||
1,
|
||||
vec![2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
87
src/problem/p3341_find_minimum_time_to_reach_last_room_i.rs
Normal file
87
src/problem/p3341_find_minimum_time_to_reach_last_room_i.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* [3341] Find Minimum Time to Reach Last Room I
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
const DIRECTIONS: [(isize, isize); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord)]
|
||||
struct State {
|
||||
x: usize,
|
||||
y: usize,
|
||||
distance: i32,
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn new(x: usize, y: usize, distance: i32) -> Self {
|
||||
Self { x, y, distance }
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for State {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
// BinaryHeap是大顶堆
|
||||
Some(other.distance.cmp(&self.distance))
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn min_time_to_reach(move_time: Vec<Vec<i32>>) -> i32 {
|
||||
let n = move_time.len();
|
||||
let m = move_time[0].len();
|
||||
|
||||
let mut distances = vec![vec![i32::MAX; m]; n];
|
||||
let mut visited = vec![vec![false; m]; n];
|
||||
let mut heap = BinaryHeap::new();
|
||||
|
||||
distances[0][0] = 0;
|
||||
heap.push(State::new(0, 0, 0));
|
||||
|
||||
while let Some(head) = heap.pop() {
|
||||
if visited[head.x][head.y] {
|
||||
continue;
|
||||
}
|
||||
visited[head.x][head.y] = true;
|
||||
|
||||
for &(dx, dy) in DIRECTIONS.iter() {
|
||||
let next = head
|
||||
.x
|
||||
.checked_add_signed(dx)
|
||||
.and_then(|x| head.y.checked_add_signed(dy).and_then(|y| Some((x, y))))
|
||||
.filter(|(x, y)| x < &n && y < &m);
|
||||
|
||||
if let Some((x, y)) = next {
|
||||
let distance = distances[head.x][head.y].max(move_time[x][y]) + 1;
|
||||
|
||||
if distances[x][y] > distance {
|
||||
distances[x][y] = distance;
|
||||
heap.push(State::new(x, y, distance));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
distances[n - 1][m - 1]
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3341() {
|
||||
assert_eq!(6, Solution::min_time_to_reach(vec![vec![0, 4], vec![4, 4]]));
|
||||
assert_eq!(
|
||||
3,
|
||||
Solution::min_time_to_reach(vec![vec![0, 0, 0], vec![0, 0, 0]])
|
||||
);
|
||||
assert_eq!(3, Solution::min_time_to_reach(vec![vec![0, 1], vec![1, 2]]));
|
||||
}
|
||||
}
|
94
src/problem/p3342_find_minimum_time_to_reach_last_room_ii.rs
Normal file
94
src/problem/p3342_find_minimum_time_to_reach_last_room_ii.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* [3342] Find Minimum Time to Reach Last Room II
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
const DIRECTIONS: [(isize, isize); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord)]
|
||||
struct State {
|
||||
x: usize,
|
||||
y: usize,
|
||||
distance: i32,
|
||||
index: i32,
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn new(x: usize, y: usize, distance: i32, index: i32) -> Self {
|
||||
Self {
|
||||
x,
|
||||
y,
|
||||
distance,
|
||||
index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for State {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
// BinaryHeap是大顶堆
|
||||
Some(other.distance.cmp(&self.distance))
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn min_time_to_reach(move_time: Vec<Vec<i32>>) -> i32 {
|
||||
let n = move_time.len();
|
||||
let m = move_time[0].len();
|
||||
|
||||
let mut distances = vec![vec![i32::MAX; m]; n];
|
||||
let mut visited = vec![vec![false; m]; n];
|
||||
let mut heap = BinaryHeap::new();
|
||||
|
||||
distances[0][0] = 0;
|
||||
heap.push(State::new(0, 0, 0, 0));
|
||||
|
||||
while let Some(head) = heap.pop() {
|
||||
if visited[head.x][head.y] {
|
||||
continue;
|
||||
}
|
||||
visited[head.x][head.y] = true;
|
||||
|
||||
for &(dx, dy) in DIRECTIONS.iter() {
|
||||
let next = head
|
||||
.x
|
||||
.checked_add_signed(dx)
|
||||
.and_then(|x| head.y.checked_add_signed(dy).and_then(|y| Some((x, y))))
|
||||
.filter(|(x, y)| x < &n && y < &m);
|
||||
|
||||
if let Some((x, y)) = next {
|
||||
let distance = distances[head.x][head.y].max(move_time[x][y])
|
||||
+ if head.index % 2 == 0 { 1 } else { 2 };
|
||||
|
||||
if distances[x][y] > distance {
|
||||
distances[x][y] = distance;
|
||||
heap.push(State::new(x, y, distance, head.index + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
distances[n - 1][m - 1]
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3342() {
|
||||
assert_eq!(7, Solution::min_time_to_reach(vec![vec![0, 4], vec![4, 4]]));
|
||||
assert_eq!(
|
||||
6,
|
||||
Solution::min_time_to_reach(vec![vec![0, 0, 0, 0], vec![0, 0, 0, 0]])
|
||||
);
|
||||
assert_eq!(4, Solution::min_time_to_reach(vec![vec![0, 1], vec![1, 2]]));
|
||||
}
|
||||
}
|
92
src/problem/p3343_count_number_of_balanced_permutations.rs
Normal file
92
src/problem/p3343_count_number_of_balanced_permutations.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* [3343] Count Number of Balanced Permutations
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
const MOD: usize = 1_000_000_007;
|
||||
|
||||
impl Solution {
|
||||
pub fn count_balanced_permutations(num: String) -> i32 {
|
||||
let num_array: Vec<usize> = num.bytes().map(|c| (c - b'0') as usize).collect();
|
||||
|
||||
let n = num_array.len();
|
||||
let sum: usize = num_array.iter().sum();
|
||||
if sum % 2 != 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let mut count = vec![0; 10];
|
||||
for &i in num_array.iter() {
|
||||
count[i] += 1;
|
||||
}
|
||||
|
||||
let target = sum / 2;
|
||||
let max_odd_count = (n + 1) / 2;
|
||||
|
||||
let mut combinations = vec![vec![0; max_odd_count + 1]; max_odd_count + 1];
|
||||
let mut dp = vec![vec![0; max_odd_count + 1]; target + 1];
|
||||
|
||||
for i in 0..=max_odd_count {
|
||||
combinations[i][i] = 1;
|
||||
combinations[i][0] = 1;
|
||||
|
||||
for j in 1..i {
|
||||
combinations[i][j] = (combinations[i - 1][j] + combinations[i - 1][j - 1]) % MOD;
|
||||
}
|
||||
}
|
||||
|
||||
dp[0][0] = 1;
|
||||
let mut prefix = 0;
|
||||
let mut total_sum = 0;
|
||||
for i in 0..=9 {
|
||||
prefix += count[i];
|
||||
total_sum += i * count[i];
|
||||
|
||||
for odd in (prefix
|
||||
.checked_sub(n - max_odd_count)
|
||||
.or_else(|| Some(0))
|
||||
.unwrap()..=prefix.min(max_odd_count))
|
||||
.rev()
|
||||
{
|
||||
let even = prefix - odd;
|
||||
|
||||
for current in (total_sum.checked_sub(target).or_else(|| Some(0)).unwrap()
|
||||
..=total_sum.min(target))
|
||||
.rev()
|
||||
{
|
||||
let mut result = 0;
|
||||
let mut j = count[i].checked_sub(even).or_else(|| Some(0)).unwrap();
|
||||
|
||||
while j <= count[i].min(odd) && i * j <= current {
|
||||
let ways = combinations[odd][j] * combinations[even][count[i] - j] % MOD;
|
||||
result = (result + ways * dp[current - i * j][odd - j] % MOD) % MOD;
|
||||
j += 1;
|
||||
}
|
||||
|
||||
dp[current][odd] = result % MOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dp[target][max_odd_count] as i32
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3343() {
|
||||
assert_eq!(2, Solution::count_balanced_permutations("123".to_string()));
|
||||
assert_eq!(1, Solution::count_balanced_permutations("112".to_string()));
|
||||
assert_eq!(
|
||||
0,
|
||||
Solution::count_balanced_permutations("12345".to_string())
|
||||
);
|
||||
}
|
||||
}
|
50
src/problem/p3355_zero_array_transformation_i.rs
Normal file
50
src/problem/p3355_zero_array_transformation_i.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* [3355] Zero Array Transformation I
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn is_zero_array(nums: Vec<i32>, queries: Vec<Vec<i32>>) -> bool {
|
||||
let n = nums.len();
|
||||
|
||||
let mut difference_array = vec![0; n + 1];
|
||||
|
||||
for query in queries {
|
||||
let left = query[0] as usize;
|
||||
let right = query[1] as usize;
|
||||
|
||||
difference_array[left] += 1;
|
||||
difference_array[right + 1] -= 1;
|
||||
}
|
||||
|
||||
let mut prefix_sum = difference_array[0];
|
||||
|
||||
for i in 1..=n {
|
||||
if prefix_sum < nums[i - 1] {
|
||||
return false;
|
||||
}
|
||||
|
||||
prefix_sum += difference_array[i];
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3355() {
|
||||
assert!(Solution::is_zero_array(vec![1, 0, 1], vec![vec![0, 2]]));
|
||||
assert!(!Solution::is_zero_array(
|
||||
vec![4, 3, 2, 1],
|
||||
vec![vec![1, 3], vec![0, 2]]
|
||||
));
|
||||
}
|
||||
}
|
71
src/problem/p3356_zero_array_transformation_ii.rs
Normal file
71
src/problem/p3356_zero_array_transformation_ii.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* [3356] Zero Array Transformation II
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn min_zero_array(nums: Vec<i32>, queries: Vec<Vec<i32>>) -> i32 {
|
||||
let (mut left, mut right) = (0, queries.len());
|
||||
|
||||
if !Self::check(&nums, &queries, right) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while left < right {
|
||||
let k = (left + right) / 2;
|
||||
if Self::check(&nums, &queries, k) {
|
||||
right = k;
|
||||
} else {
|
||||
left = k + 1;
|
||||
}
|
||||
}
|
||||
|
||||
left as i32
|
||||
}
|
||||
|
||||
fn check(nums: &Vec<i32>, queries: &Vec<Vec<i32>>, k: usize) -> bool {
|
||||
let n = nums.len();
|
||||
let mut difference_array = vec![0; n + 1];
|
||||
|
||||
for query in queries[..k].iter() {
|
||||
difference_array[query[0] as usize] += query[2];
|
||||
difference_array[query[1] as usize + 1] -= query[2];
|
||||
}
|
||||
|
||||
let mut prefix_sum = difference_array[0];
|
||||
|
||||
for (i, &v) in difference_array[1..].iter().enumerate() {
|
||||
if prefix_sum < nums[i] {
|
||||
return false;
|
||||
}
|
||||
|
||||
prefix_sum += v;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3356() {
|
||||
assert_eq!(
|
||||
2,
|
||||
Solution::min_zero_array(
|
||||
vec![2, 0, 2],
|
||||
vec![vec![0, 2, 1], vec![0, 2, 1], vec![1, 1, 3]]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
-1,
|
||||
Solution::min_zero_array(vec![4, 3, 2, 1], vec![vec![1, 3, 2], vec![0, 2, 1]])
|
||||
);
|
||||
}
|
||||
}
|
73
src/problem/p3362_zero_array_transformation_iii.rs
Normal file
73
src/problem/p3362_zero_array_transformation_iii.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* [3362] Zero Array Transformation III
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
impl Solution {
|
||||
pub fn max_removal(nums: Vec<i32>, mut queries: Vec<Vec<i32>>) -> i32 {
|
||||
queries.sort_unstable_by(|a, b| a[0].cmp(&b[0]));
|
||||
|
||||
let mut heap = BinaryHeap::new();
|
||||
let mut difference_array = vec![0; nums.len() + 1];
|
||||
let mut prefix_sum = 0;
|
||||
let mut pos = 0;
|
||||
|
||||
for i in 0..nums.len() {
|
||||
prefix_sum += difference_array[i];
|
||||
|
||||
while pos < queries.len() && queries[pos][0] as usize == i {
|
||||
heap.push(queries[pos][1] as usize);
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
while prefix_sum < nums[i] {
|
||||
if let Some(&right) = heap.peek() {
|
||||
if right >= i {
|
||||
prefix_sum += 1;
|
||||
difference_array[right + 1] -= 1;
|
||||
heap.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if prefix_sum < nums[i] {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
heap.len() as i32
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3362() {
|
||||
assert_eq!(
|
||||
1,
|
||||
Solution::max_removal(vec![2, 0, 2], vec![vec![0, 2], vec![0, 2], vec![1, 1]])
|
||||
);
|
||||
assert_eq!(
|
||||
2,
|
||||
Solution::max_removal(
|
||||
vec![1, 1, 1, 1],
|
||||
vec![vec![1, 3], vec![0, 2], vec![1, 3], vec![1, 2]]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
-1,
|
||||
Solution::max_removal(vec![1, 2, 3, 4], vec![vec![0, 3]])
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* [3372] Maximize the Number of Target Nodes After Connecting Trees I
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::VecDeque;
|
||||
|
||||
impl Solution {
|
||||
pub fn max_target_nodes(edges1: Vec<Vec<i32>>, edges2: Vec<Vec<i32>>, k: i32) -> Vec<i32> {
|
||||
// 首先构建邻接矩阵
|
||||
let adjacent_matrix1 = Self::construct_adjacent_matrix(&edges1);
|
||||
let adjacent_matrix2 = Self::construct_adjacent_matrix(&edges2);
|
||||
|
||||
let target_pointer_counts1 = Self::calculate_target_pointer_counts(&adjacent_matrix1, k);
|
||||
let target_pointer_counts2 =
|
||||
Self::calculate_target_pointer_counts(&adjacent_matrix2, k - 1);
|
||||
let max_count = *target_pointer_counts2.iter().max().unwrap();
|
||||
|
||||
target_pointer_counts1
|
||||
.iter()
|
||||
.map(|&c| c + max_count)
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn construct_adjacent_matrix(edges: &Vec<Vec<i32>>) -> Vec<Vec<usize>> {
|
||||
let n = edges.len() + 1;
|
||||
let mut adjacent_matrix = vec![vec![]; n];
|
||||
|
||||
for edge in edges.iter() {
|
||||
let first = edge[0] as usize;
|
||||
let second = edge[1] as usize;
|
||||
|
||||
adjacent_matrix[first].push(second);
|
||||
adjacent_matrix[second].push(first);
|
||||
}
|
||||
|
||||
adjacent_matrix
|
||||
}
|
||||
|
||||
fn calculate_target_pointer_counts(
|
||||
adjacent_matrix: &Vec<Vec<usize>>,
|
||||
distance: i32,
|
||||
) -> Vec<i32> {
|
||||
let mut queue = VecDeque::new();
|
||||
|
||||
(0..adjacent_matrix.len())
|
||||
.map(|i| {
|
||||
let mut count = 0;
|
||||
|
||||
queue.clear();
|
||||
if distance >= 0 {
|
||||
queue.push_back((i, 0, None));
|
||||
}
|
||||
|
||||
while let Some((pos, c, parent)) = queue.pop_front() {
|
||||
count += 1;
|
||||
|
||||
if c + 1 <= distance {
|
||||
for &next in adjacent_matrix[pos].iter() {
|
||||
if parent.filter(|x| x == &next).is_some() {
|
||||
continue;
|
||||
}
|
||||
|
||||
queue.push_back((next, c + 1, Some(pos)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3372() {
|
||||
assert_eq!(
|
||||
vec![1, 1],
|
||||
Solution::max_target_nodes(vec![vec![0, 1]], vec![vec![0, 1]], 0)
|
||||
);
|
||||
assert_eq!(
|
||||
vec![9, 7, 9, 8, 8],
|
||||
Solution::max_target_nodes(
|
||||
vec![vec![0, 1], vec![0, 2], vec![2, 3], vec![2, 4]],
|
||||
vec![
|
||||
vec![0, 1],
|
||||
vec![0, 2],
|
||||
vec![0, 3],
|
||||
vec![2, 7],
|
||||
vec![1, 4],
|
||||
vec![4, 5],
|
||||
vec![4, 6]
|
||||
],
|
||||
2
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
vec![6, 3, 3, 3, 3],
|
||||
Solution::max_target_nodes(
|
||||
vec![vec![0, 1], vec![0, 2], vec![0, 3], vec![0, 4]],
|
||||
vec![vec![0, 1], vec![1, 2], vec![2, 3]],
|
||||
1
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* [3373] Maximize the Number of Target Nodes After Connecting Trees II
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::VecDeque;
|
||||
|
||||
impl Solution {
|
||||
pub fn max_target_nodes(edges1: Vec<Vec<i32>>, edges2: Vec<Vec<i32>>) -> Vec<i32> {
|
||||
let adjacent_matrix1 = Self::construct_adjacent_matrix(&edges1);
|
||||
let adjacent_matrix2 = Self::construct_adjacent_matrix(&edges2);
|
||||
|
||||
let (even_count1, odd_count1, color1) =
|
||||
Self::calculate_target_pointer_counts(&adjacent_matrix1);
|
||||
let (even_count2, odd_count2, _) = Self::calculate_target_pointer_counts(&adjacent_matrix2);
|
||||
|
||||
let max_count = odd_count2.max(even_count2);
|
||||
|
||||
(0..adjacent_matrix1.len())
|
||||
.map(|i| {
|
||||
if color1[i] {
|
||||
even_count1 + max_count
|
||||
} else {
|
||||
odd_count1 + max_count
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn construct_adjacent_matrix(edges: &Vec<Vec<i32>>) -> Vec<Vec<usize>> {
|
||||
let n = edges.len() + 1;
|
||||
let mut adjacent_matrix = vec![vec![]; n];
|
||||
|
||||
for edge in edges.iter() {
|
||||
let first = edge[0] as usize;
|
||||
let second = edge[1] as usize;
|
||||
|
||||
adjacent_matrix[first].push(second);
|
||||
adjacent_matrix[second].push(first);
|
||||
}
|
||||
|
||||
adjacent_matrix
|
||||
}
|
||||
|
||||
fn calculate_target_pointer_counts(adjacent_matrix: &Vec<Vec<usize>>) -> (i32, i32, Vec<bool>) {
|
||||
let mut queue = VecDeque::new();
|
||||
// 染色数组
|
||||
// true表示距离为偶数
|
||||
// false表示距离为奇数
|
||||
let mut color = vec![false; adjacent_matrix.len()];
|
||||
// 距离为偶数的计数
|
||||
let mut result = 0;
|
||||
|
||||
queue.push_back((0, 0, None));
|
||||
|
||||
while let Some((pos, c, parent)) = queue.pop_front() {
|
||||
if c % 2 == 0 {
|
||||
color[pos] = true;
|
||||
result += 1;
|
||||
}
|
||||
|
||||
for &next in adjacent_matrix[pos].iter() {
|
||||
if parent.filter(|x| x == &next).is_some() {
|
||||
continue;
|
||||
}
|
||||
|
||||
queue.push_back((next, c + 1, Some(pos)));
|
||||
}
|
||||
}
|
||||
|
||||
(result, adjacent_matrix.len() as i32 - result, color)
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3373() {
|
||||
assert_eq!(
|
||||
vec![8, 7, 7, 8, 8],
|
||||
Solution::max_target_nodes(
|
||||
vec![vec![0, 1], vec![0, 2], vec![2, 3], vec![2, 4]],
|
||||
vec![
|
||||
vec![0, 1],
|
||||
vec![0, 2],
|
||||
vec![0, 3],
|
||||
vec![2, 7],
|
||||
vec![1, 4],
|
||||
vec![4, 5],
|
||||
vec![4, 6]
|
||||
]
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
vec![3, 6, 6, 6, 6],
|
||||
Solution::max_target_nodes(
|
||||
vec![vec![0, 1], vec![0, 2], vec![0, 3], vec![0, 4]],
|
||||
vec![vec![0, 1], vec![1, 2], vec![2, 3]]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* [3392] Count Subarrays of Length Three With a Condition
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn count_subarrays(nums: Vec<i32>) -> i32 {
|
||||
nums.iter()
|
||||
.enumerate()
|
||||
.skip(2)
|
||||
.filter_map(|(i, &v)| {
|
||||
if (nums[i - 2] + v) * 2 == nums[i - 1] {
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.count() as i32
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3392() {
|
||||
assert_eq!(1, Solution::count_subarrays(vec![1, 2, 1, 4, 1]));
|
||||
assert_eq!(0, Solution::count_subarrays(vec![1, 1, 1]));
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* [3403] Find the Lexicographically Largest String From the Box I
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn answer_string(word: String, num_friends: i32) -> String {
|
||||
// When there is only one person, the word can not be split.
|
||||
if num_friends == 1 {
|
||||
return word;
|
||||
}
|
||||
|
||||
let word: Vec<u8> = word.bytes().collect();
|
||||
let length = word.len() - num_friends as usize + 1;
|
||||
let mut result: Option<&[u8]> = None;
|
||||
|
||||
for i in 0..word.len() {
|
||||
let end = (i + length).min(word.len());
|
||||
let w = &word[i..(i + length).min(word.len())];
|
||||
|
||||
if let Some(r) = result {
|
||||
if w > r {
|
||||
result = Some(w)
|
||||
}
|
||||
} else {
|
||||
result = Some(w);
|
||||
}
|
||||
}
|
||||
|
||||
String::from_utf8(result.unwrap().into_iter().map(|x| *x).collect()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3403() {
|
||||
assert_eq!("gh", Solution::answer_string("gh".to_string(), 1));
|
||||
assert_eq!("dbc", Solution::answer_string("dbca".to_string(), 2));
|
||||
assert_eq!("g", Solution::answer_string("gggg".to_string(), 4));
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* [3442] Maximum Difference Between Even and Odd Frequency I
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
use std::collections::HashMap;
|
||||
|
||||
impl Solution {
|
||||
pub fn max_difference(s: String) -> i32 {
|
||||
let mut frequency_map = HashMap::new();
|
||||
|
||||
for c in s.bytes() {
|
||||
let entry = frequency_map.entry(c).or_insert(0);
|
||||
*entry += 1;
|
||||
}
|
||||
|
||||
let mut odd_max = 0;
|
||||
let mut even_min = i32::MAX;
|
||||
|
||||
for &v in frequency_map.values() {
|
||||
if v % 2 == 0 {
|
||||
even_min = even_min.min(v);
|
||||
} else {
|
||||
odd_max = odd_max.max(v);
|
||||
}
|
||||
}
|
||||
|
||||
odd_max - even_min
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_3442() {
|
||||
assert_eq!(3, Solution::max_difference("aaaaabbc".to_string()));
|
||||
assert_eq!(1, Solution::max_difference("abcabcab".to_string()));
|
||||
}
|
||||
}
|
50
src/problem/p386_lexicographical_numbers.rs
Normal file
50
src/problem/p386_lexicographical_numbers.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* [386] Lexicographical Numbers
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn lexical_order(n: i32) -> Vec<i32> {
|
||||
let mut result = Vec::with_capacity(n as usize);
|
||||
|
||||
for i in 1..10 {
|
||||
Self::search(&mut result, i, n);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn search(result: &mut Vec<i32>, mut prefix: i32, n: i32) {
|
||||
if prefix <= n {
|
||||
result.push(prefix);
|
||||
}
|
||||
|
||||
prefix = prefix * 10;
|
||||
|
||||
for i in 0..10 {
|
||||
if prefix + i > n {
|
||||
break;
|
||||
}
|
||||
|
||||
Self::search(result, prefix + i, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_386() {
|
||||
assert_eq!(vec![1, 2], Solution::lexical_order(2));
|
||||
assert_eq!(
|
||||
vec![1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||
Solution::lexical_order(13)
|
||||
);
|
||||
}
|
||||
}
|
56
src/problem/p440_k_th_smallest_in_lexicographical_order.rs
Normal file
56
src/problem/p440_k_th_smallest_in_lexicographical_order.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* [440] K-th Smallest in Lexicographical Order
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn find_kth_number(n: i32, mut k: i32) -> i32 {
|
||||
let mut currrent = 1;
|
||||
let n = n as i64;
|
||||
k -= 1;
|
||||
|
||||
while k > 0 {
|
||||
let steps = Self::calculate_steps(currrent, n);
|
||||
// If steps <= k, then the number is in the tree of next current (at least).
|
||||
if steps <= k {
|
||||
k -= steps;
|
||||
currrent += 1;
|
||||
} else {
|
||||
// The number is in the current tree.
|
||||
currrent = currrent * 10;
|
||||
k -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
currrent as i32
|
||||
}
|
||||
|
||||
/// Calculate the count of number with prefix current.
|
||||
fn calculate_steps(current: i64, n: i64) -> i32 {
|
||||
let mut result = 0;
|
||||
let (mut first, mut last) = (current, current);
|
||||
|
||||
while first <= n {
|
||||
result += n.min(last) - first + 1;
|
||||
first = first * 10;
|
||||
last = last * 10 + 9;
|
||||
}
|
||||
|
||||
result as i32
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_440() {
|
||||
assert_eq!(10, Solution::find_kth_number(13, 2));
|
||||
assert_eq!(1, Solution::find_kth_number(1, 1));
|
||||
}
|
||||
}
|
53
src/problem/p75_sort_colors.rs
Normal file
53
src/problem/p75_sort_colors.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* [75] Sort Colors
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
impl Solution {
|
||||
pub fn sort_colors(nums: &mut Vec<i32>) {
|
||||
let (mut zero_count, mut one_count, mut two_count) = (0, 0, 0);
|
||||
|
||||
for i in nums.iter() {
|
||||
match i {
|
||||
&0 => zero_count += 1,
|
||||
&1 => one_count += 1,
|
||||
&2 => two_count += 1,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let mut pos = 0;
|
||||
for _ in 0..zero_count {
|
||||
nums[pos] = 0;
|
||||
pos += 1;
|
||||
}
|
||||
for _ in 0..one_count {
|
||||
nums[pos] = 1;
|
||||
pos += 1;
|
||||
}
|
||||
for _ in 0..two_count {
|
||||
nums[pos] = 2;
|
||||
pos += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_75() {
|
||||
let mut input = vec![2, 0, 2, 1, 1, 0];
|
||||
Solution::sort_colors(&mut input);
|
||||
assert_eq!(vec![0, 0, 1, 1, 2, 2], input);
|
||||
|
||||
let mut input = vec![2, 0, 1];
|
||||
Solution::sort_colors(&mut input);
|
||||
assert_eq!(vec![0, 1, 2], input);
|
||||
}
|
||||
}
|
50
src/problem/p790_domino_and_tromino_tiling.rs
Normal file
50
src/problem/p790_domino_and_tromino_tiling.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* [790] Domino and Tromino Tiling
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
|
||||
const MOD: i32 = 1_000_000_007;
|
||||
|
||||
impl Solution {
|
||||
pub fn num_tilings(n: i32) -> i32 {
|
||||
let n = n as usize;
|
||||
let mut dp = vec![0; n + 1];
|
||||
dp[0] = 1;
|
||||
let mut prefix = 0;
|
||||
|
||||
// dp的最后必须是平整的
|
||||
// dp[n] = dp[n - 1] + dp[n - 2] + for i in 0..=n-3 Sum(dp[i] * 2)
|
||||
for i in 1..=n {
|
||||
dp[i] = dp[i - 1] % MOD;
|
||||
|
||||
if i >= 2 {
|
||||
dp[i] = (dp[i] + dp[i - 2]) % MOD;
|
||||
}
|
||||
|
||||
if i >= 3 {
|
||||
prefix = (prefix + dp[i - 3] * 2 % MOD) % MOD;
|
||||
dp[i] = (dp[i] + prefix) % MOD;
|
||||
}
|
||||
}
|
||||
|
||||
dp[n]
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_790() {
|
||||
assert_eq!(1, Solution::num_tilings(1));
|
||||
assert_eq!(2, Solution::num_tilings(2));
|
||||
assert_eq!(5, Solution::num_tilings(3));
|
||||
assert_eq!(11, Solution::num_tilings(4));
|
||||
assert_eq!(312342182, Solution::num_tilings(30));
|
||||
}
|
||||
}
|
111
src/problem/p838_push_dominoes.rs
Normal file
111
src/problem/p838_push_dominoes.rs
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* [838] Push Dominoes
|
||||
*/
|
||||
pub struct Solution {}
|
||||
|
||||
// submission codes start here
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||
enum State {
|
||||
Left,
|
||||
Right,
|
||||
Untouched,
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn push_dominoes(dominoes: String) -> String {
|
||||
let mut dominoes: Vec<State> = dominoes
|
||||
.chars()
|
||||
.map(|c| match c {
|
||||
'L' => State::Left,
|
||||
'R' => State::Right,
|
||||
'.' => State::Untouched,
|
||||
_ => unimplemented!(),
|
||||
})
|
||||
.collect();
|
||||
let n = dominoes.len();
|
||||
|
||||
// 为双指针插入头尾伪节点
|
||||
dominoes.insert(0, State::Untouched);
|
||||
dominoes.push(State::Untouched);
|
||||
|
||||
let (mut left, mut right) = (0, 1);
|
||||
|
||||
// 不能判断右指针
|
||||
// 左指针才是遍历完成的信息
|
||||
while left <= n {
|
||||
while right <= n && dominoes[right] == State::Untouched {
|
||||
right += 1;
|
||||
}
|
||||
|
||||
// 找到没有推动的区间(left, right)
|
||||
if right - left > 1 {
|
||||
let (mut inner_left, mut inner_right) = (left + 1, right - 1);
|
||||
|
||||
match (dominoes[left], dominoes[right]) {
|
||||
(State::Untouched, State::Left) | (State::Left, State::Left) => {
|
||||
while inner_left <= inner_right {
|
||||
dominoes[inner_left] = State::Left;
|
||||
inner_left += 1;
|
||||
}
|
||||
}
|
||||
(State::Right, State::Untouched) | (State::Right, State::Right) => {
|
||||
while inner_left <= inner_right {
|
||||
dominoes[inner_left] = State::Right;
|
||||
inner_left += 1;
|
||||
}
|
||||
}
|
||||
(State::Right, State::Left) => {
|
||||
while inner_left < inner_right {
|
||||
// 注意需要同时修改
|
||||
let l = Self::between_left_right(&mut dominoes, inner_left);
|
||||
let r = Self::between_left_right(&mut dominoes, inner_right);
|
||||
dominoes[inner_left] = l;
|
||||
dominoes[inner_right] = r;
|
||||
inner_left += 1;
|
||||
inner_right -= 1;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
left = right;
|
||||
right += 1;
|
||||
}
|
||||
|
||||
dominoes[1..=n]
|
||||
.iter()
|
||||
.map(|x| match x {
|
||||
State::Left => 'L',
|
||||
State::Right => 'R',
|
||||
State::Untouched => '.',
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn between_left_right(dominoes: &mut Vec<State>, pos: usize) -> State {
|
||||
match (dominoes[pos - 1], dominoes[pos + 1]) {
|
||||
(State::Right, State::Untouched) => State::Right,
|
||||
(State::Untouched, State::Left) => State::Left,
|
||||
// 其他情况都不会影响中间的
|
||||
_ => dominoes[pos],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// submission codes end
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_838() {
|
||||
assert_eq!("LL.RR", Solution::push_dominoes(".L.R.".to_owned()));
|
||||
assert_eq!("RR.L", Solution::push_dominoes("RR.L".to_owned()));
|
||||
assert_eq!(
|
||||
"LL.RR.LLRRLL..",
|
||||
Solution::push_dominoes(".L.R...LR..L..".to_owned())
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user