add 20250217 commit
This commit is contained in:
commit
338f74cb9e
|
@ -491,4 +491,132 @@ mod p1706_where_will_the_ball_fall;
|
||||||
|
|
||||||
mod p1299_replace_elements_with_greatest_element_on_right_side;
|
mod p1299_replace_elements_with_greatest_element_on_right_side;
|
||||||
|
|
||||||
|
mod p2080_range_frequency_queries;
|
||||||
|
|
||||||
|
mod p624_maximum_distance_in_arrays;
|
||||||
|
|
||||||
|
mod p2595_number_of_even_and_odd_bits;
|
||||||
|
|
||||||
|
mod p2209_minimum_white_tiles_after_covering_with_carpets;
|
||||||
|
|
||||||
|
mod p2506_count_pairs_of_similar_strings;
|
||||||
|
|
||||||
|
mod p1206_design_skiplist;
|
||||||
|
|
||||||
|
mod p1656_design_an_ordered_stream;
|
||||||
|
|
||||||
|
mod p2502_design_memory_allocator;
|
||||||
|
|
||||||
|
mod p1472_design_browser_history;
|
||||||
|
|
||||||
|
mod p2353_design_a_food_rating_system;
|
||||||
|
|
||||||
|
mod p131_palindrome_partitioning;
|
||||||
|
|
||||||
|
mod p132_palindrome_partitioning_ii;
|
||||||
|
|
||||||
|
mod p1278_palindrome_partitioning_iii;
|
||||||
|
|
||||||
|
mod p1745_palindrome_partitioning_iv;
|
||||||
|
|
||||||
|
mod p1328_break_a_palindrome;
|
||||||
|
|
||||||
|
mod p2588_count_the_number_of_beautiful_subarrays;
|
||||||
|
|
||||||
|
mod p2597_the_number_of_beautiful_subsets;
|
||||||
|
|
||||||
|
mod p2234_maximum_total_beauty_of_the_gardens;
|
||||||
|
|
||||||
|
mod p2070_most_beautiful_item_for_each_query;
|
||||||
|
|
||||||
|
mod p2269_find_the_k_beauty_of_a_number;
|
||||||
|
|
||||||
|
mod p2012_sum_of_beauty_in_the_array;
|
||||||
|
|
||||||
|
mod p3305_count_of_substrings_containing_every_vowel_and_k_consonants_i;
|
||||||
|
|
||||||
|
mod p3306_count_of_substrings_containing_every_vowel_and_k_consonants_ii;
|
||||||
|
|
||||||
|
mod p3340_check_balanced_string;
|
||||||
|
|
||||||
|
mod p3110_score_of_a_string;
|
||||||
|
|
||||||
|
mod p2272_substring_with_largest_variance;
|
||||||
|
|
||||||
|
mod p1963_minimum_number_of_swaps_to_make_the_string_balanced;
|
||||||
|
|
||||||
|
mod p2614_prime_in_diagonal;
|
||||||
|
|
||||||
|
mod p2610_convert_an_array_into_a_2d_array_with_conditions;
|
||||||
|
|
||||||
|
mod p2612_minimum_reverse_operations;
|
||||||
|
|
||||||
|
mod p2680_maximum_or;
|
||||||
|
|
||||||
|
mod p2643_row_with_maximum_ones;
|
||||||
|
|
||||||
|
mod p2116_check_if_a_parentheses_string_can_be_valid;
|
||||||
|
|
||||||
|
mod p2255_count_prefixes_of_a_given_string;
|
||||||
|
|
||||||
|
mod p2711_difference_of_number_of_distinct_values_on_diagonals;
|
||||||
|
|
||||||
|
mod p2829_determine_the_minimum_sum_of_a_k_avoiding_array;
|
||||||
|
|
||||||
|
mod p2712_minimum_cost_to_make_all_characters_equal;
|
||||||
|
|
||||||
|
mod p2716_minimize_string_length;
|
||||||
|
|
||||||
|
mod p2360_longest_cycle_in_a_graph;
|
||||||
|
|
||||||
|
mod p2109_adding_spaces_to_a_string;
|
||||||
|
|
||||||
|
mod p2278_percentage_of_letter_in_string;
|
||||||
|
|
||||||
|
mod p2140_solving_questions_with_brainpower;
|
||||||
|
|
||||||
|
mod p2873_maximum_value_of_an_ordered_triplet_i;
|
||||||
|
|
||||||
|
mod p2874_maximum_value_of_an_ordered_triplet_ii;
|
||||||
|
|
||||||
|
mod p1123_lowest_common_ancestor_of_deepest_leaves;
|
||||||
|
|
||||||
|
mod p1863_sum_of_all_subset_xor_totals;
|
||||||
|
|
||||||
|
mod p368_largest_divisible_subset;
|
||||||
|
|
||||||
|
mod p416_partition_equal_subset_sum;
|
||||||
|
|
||||||
|
mod p3396_minimum_number_of_operations_to_make_elements_in_array_distinct;
|
||||||
|
|
||||||
|
mod p2999_count_the_number_of_powerful_integers;
|
||||||
|
mod p3375_minimum_operations_to_make_array_values_equal_to_k;
|
||||||
|
|
||||||
|
mod p2843_count_symmetric_integers;
|
||||||
|
|
||||||
|
mod p3272_find_the_count_of_good_integers;
|
||||||
|
|
||||||
|
mod p1922_count_good_numbers;
|
||||||
|
|
||||||
|
mod p1534_count_good_triplets;
|
||||||
|
|
||||||
|
mod p2179_count_good_triplets_in_an_array;
|
||||||
|
|
||||||
|
mod p2537_count_the_number_of_good_subarrays;
|
||||||
|
|
||||||
|
mod p2176_count_equal_and_divisible_pairs_in_an_array;
|
||||||
|
|
||||||
|
mod p2364_count_number_of_bad_pairs;
|
||||||
|
|
||||||
|
mod p2563_count_the_number_of_fair_pairs;
|
||||||
|
|
||||||
|
mod p781_rabbits_in_forest;
|
||||||
|
|
||||||
|
mod p2145_count_the_hidden_sequences;
|
||||||
|
|
||||||
|
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 p1287_element_appearing_more_than_25_in_sorted_array;
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* [1123] Lowest Common Ancestor of Deepest Leaves
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
use crate::util::tree::{to_tree, TreeNode};
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
// Definition for a binary tree node.
|
||||||
|
// #[derive(Debug, PartialEq, Eq)]
|
||||||
|
// pub struct TreeNode {
|
||||||
|
// pub val: i32,
|
||||||
|
// pub left: Option<Rc<RefCell<TreeNode>>>,
|
||||||
|
// pub right: Option<Rc<RefCell<TreeNode>>>,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl TreeNode {
|
||||||
|
// #[inline]
|
||||||
|
// pub fn new(val: i32) -> Self {
|
||||||
|
// TreeNode {
|
||||||
|
// val,
|
||||||
|
// left: None,
|
||||||
|
// right: None
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn lca_deepest_leaves(
|
||||||
|
root: Option<Rc<RefCell<TreeNode>>>,
|
||||||
|
) -> Option<Rc<RefCell<TreeNode>>> {
|
||||||
|
if let Some(root) = root {
|
||||||
|
Self::search(&root).1
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// (子树的深度,lca)
|
||||||
|
fn search(node: &Rc<RefCell<TreeNode>>) -> (i32, Option<Rc<RefCell<TreeNode>>>) {
|
||||||
|
let (left_deep, left_lca) = if let Some(left) = node.borrow().left.as_ref() {
|
||||||
|
Self::search(left)
|
||||||
|
} else {
|
||||||
|
(0, None)
|
||||||
|
};
|
||||||
|
|
||||||
|
let (right_deep, right_lca) = if let Some(right) = node.borrow().right.as_ref() {
|
||||||
|
Self::search(right)
|
||||||
|
} else {
|
||||||
|
(0, None)
|
||||||
|
};
|
||||||
|
|
||||||
|
match left_deep.cmp(&right_deep) {
|
||||||
|
Ordering::Greater => (left_deep + 1, left_lca),
|
||||||
|
Ordering::Less => (right_deep + 1, right_lca),
|
||||||
|
Ordering::Equal => (left_deep + 1, Some(node.clone())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1123() {
|
||||||
|
let node = Solution::lca_deepest_leaves(to_tree(vec![
|
||||||
|
Some(3),
|
||||||
|
Some(5),
|
||||||
|
Some(1),
|
||||||
|
Some(6),
|
||||||
|
Some(2),
|
||||||
|
Some(0),
|
||||||
|
Some(8),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Some(7),
|
||||||
|
Some(4),
|
||||||
|
]));
|
||||||
|
|
||||||
|
assert_eq!(to_tree(vec![Some(2), Some(7), Some(4)]), node);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
to_tree(vec![Some(1)]),
|
||||||
|
Solution::lca_deepest_leaves(to_tree(vec![Some(1)]))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
to_tree(vec![Some(2)]),
|
||||||
|
Solution::lca_deepest_leaves(to_tree(vec![Some(0), Some(1), Some(3), None, Some(2)]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
189
src/problem/p1206_design_skiplist.rs
Normal file
189
src/problem/p1206_design_skiplist.rs
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
/**
|
||||||
|
* [1206] Design Skiplist
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use rand::Rng;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
struct SkiplistNode {
|
||||||
|
right: Option<Rc<RefCell<SkiplistNode>>>,
|
||||||
|
down: Option<Rc<RefCell<SkiplistNode>>>,
|
||||||
|
value: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeCell = Rc<RefCell<SkiplistNode>>;
|
||||||
|
|
||||||
|
struct Skiplist {
|
||||||
|
head: Rc<RefCell<SkiplistNode>>,
|
||||||
|
random_engine: rand::rngs::ThreadRng,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `&self` means the method takes an immutable reference.
|
||||||
|
* If you need a mutable reference, change it to `&mut self` instead.
|
||||||
|
*/
|
||||||
|
impl Skiplist {
|
||||||
|
fn create_node(value: i32) -> NodeCell {
|
||||||
|
Rc::new(RefCell::new(SkiplistNode {
|
||||||
|
right: None,
|
||||||
|
down: None,
|
||||||
|
value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
head: Self::create_node(-1),
|
||||||
|
random_engine: rand::thread_rng(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search(&self, target: i32) -> bool {
|
||||||
|
let mut node = Some(self.head.clone());
|
||||||
|
let mut queue = vec![];
|
||||||
|
|
||||||
|
while let Some(real_node) = node {
|
||||||
|
node = if real_node
|
||||||
|
.borrow()
|
||||||
|
.right
|
||||||
|
.clone()
|
||||||
|
.filter(|x| x.borrow().value <= target)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
real_node.borrow().right.clone()
|
||||||
|
} else {
|
||||||
|
queue.push(real_node.clone());
|
||||||
|
real_node.borrow().down.clone()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
queue
|
||||||
|
.last()
|
||||||
|
.filter(|x| x.borrow().value == target)
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&mut self, num: i32) {
|
||||||
|
let mut path = vec![];
|
||||||
|
let mut node = Some(self.head.clone());
|
||||||
|
|
||||||
|
// 找链表中所有小于num的节点
|
||||||
|
while let Some(real_node) = node {
|
||||||
|
node = if real_node
|
||||||
|
.borrow()
|
||||||
|
.right
|
||||||
|
.as_ref()
|
||||||
|
.filter(|x| x.borrow().value <= num)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
real_node.borrow().right.clone()
|
||||||
|
} else {
|
||||||
|
path.push(real_node.clone());
|
||||||
|
real_node.borrow().down.as_ref().map(|x| x.clone())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut insert = true;
|
||||||
|
let mut down_node = None;
|
||||||
|
|
||||||
|
while insert && !path.is_empty() {
|
||||||
|
if let Some(insert_node) = path.pop() {
|
||||||
|
// 添加新的节点
|
||||||
|
let right_node = insert_node.borrow_mut().right.take();
|
||||||
|
insert_node.borrow_mut().right = Some(Rc::new(RefCell::new(SkiplistNode {
|
||||||
|
right: right_node,
|
||||||
|
down: down_node.take(),
|
||||||
|
value: num,
|
||||||
|
})));
|
||||||
|
|
||||||
|
down_node = insert_node.borrow().right.as_ref().map(|x| x.clone());
|
||||||
|
// 50%的概率决定是否添加下一级索引
|
||||||
|
insert = self.random_engine.gen_bool(0.5);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增头结点
|
||||||
|
// 这里新增一层
|
||||||
|
if insert {
|
||||||
|
let node = Skiplist::create_node(-1);
|
||||||
|
node.borrow_mut().down = Some(self.head.clone());
|
||||||
|
self.head = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn erase(&self, num: i32) -> bool {
|
||||||
|
let mut deleted = false;
|
||||||
|
let mut node = Some(self.head.clone());
|
||||||
|
|
||||||
|
while let Some(mut real_node) = node {
|
||||||
|
node = if real_node
|
||||||
|
.borrow()
|
||||||
|
.right
|
||||||
|
.as_ref()
|
||||||
|
.filter(|x| x.borrow().value < num)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
real_node.borrow().right.clone()
|
||||||
|
} else {
|
||||||
|
real_node.borrow().down.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
if real_node
|
||||||
|
.borrow()
|
||||||
|
.right
|
||||||
|
.as_ref()
|
||||||
|
.filter(|x| x.borrow().value == num)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
deleted = true;
|
||||||
|
let right = real_node
|
||||||
|
.borrow_mut()
|
||||||
|
.right
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.borrow()
|
||||||
|
.right
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| x.clone());
|
||||||
|
real_node.borrow_mut().right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Your Skiplist object will be instantiated and called as such:
|
||||||
|
* let obj = Skiplist::new();
|
||||||
|
* let ret_1: bool = obj.search(target);
|
||||||
|
* obj.add(num);
|
||||||
|
* let ret_3: bool = obj.erase(num);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1206() {
|
||||||
|
let mut list = Skiplist::new();
|
||||||
|
|
||||||
|
list.add(1);
|
||||||
|
list.add(2);
|
||||||
|
list.add(3);
|
||||||
|
assert!(!list.search(0));
|
||||||
|
list.add(4);
|
||||||
|
assert!(list.search(1));
|
||||||
|
assert!(!list.erase(0));
|
||||||
|
assert!(list.erase(1));
|
||||||
|
assert!(!list.search(1));
|
||||||
|
}
|
||||||
|
}
|
60
src/problem/p1278_palindrome_partitioning_iii.rs
Normal file
60
src/problem/p1278_palindrome_partitioning_iii.rs
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/**
|
||||||
|
* [1278] Palindrome Partitioning III
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn palindrome_partition(s: String, k: i32) -> i32 {
|
||||||
|
let s: Vec<char> = s.chars().collect();
|
||||||
|
let length = s.len();
|
||||||
|
|
||||||
|
// cost[i][j]
|
||||||
|
// 将 s[i..=j] 修改为回文串需要的修改次数
|
||||||
|
let mut cost = vec![vec![0; length]; length];
|
||||||
|
|
||||||
|
for span in 2..=length {
|
||||||
|
for i in 0..=length - span {
|
||||||
|
let j = i + span - 1;
|
||||||
|
|
||||||
|
cost[i][j] = cost[i + 1][j - 1] + if s[i] == s[j] { 0 } else { 1 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let k = k as usize;
|
||||||
|
// dp[i][j]
|
||||||
|
// 将s[..i]分割为j个回文串需要的修改次数
|
||||||
|
let mut dp = vec![vec![i32::MAX; k + 1]; length + 1];
|
||||||
|
|
||||||
|
for i in 1..=length {
|
||||||
|
for j in 1..=i.min(k) {
|
||||||
|
if j == 1 {
|
||||||
|
dp[i][j] = cost[0][i - 1];
|
||||||
|
} else {
|
||||||
|
// 这里k从j - 1开始枚举是因为前面需要进行j - 1次分割时
|
||||||
|
// 字符串的长度必须大于等于j - 1
|
||||||
|
for k in j - 1..i {
|
||||||
|
dp[i][j] = dp[i][j].min(dp[k][j - 1] + cost[k][i - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dp[length][k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1278() {
|
||||||
|
assert_eq!(1, Solution::palindrome_partition("abc".to_owned(), 2));
|
||||||
|
assert_eq!(0, Solution::palindrome_partition("aabbc".to_owned(), 3));
|
||||||
|
assert_eq!(0, Solution::palindrome_partition("leetcode".to_owned(), 8));
|
||||||
|
}
|
||||||
|
}
|
63
src/problem/p131_palindrome_partitioning.rs
Normal file
63
src/problem/p131_palindrome_partitioning.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* [131] Palindrome Partitioning
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn partition(s: String) -> Vec<Vec<String>> {
|
||||||
|
let s: Vec<char> = s.chars().collect();
|
||||||
|
let length = s.len();
|
||||||
|
|
||||||
|
let mut result = vec![];
|
||||||
|
let mut current: Vec<String> = vec![];
|
||||||
|
let mut dp = vec![vec![true; length]; length];
|
||||||
|
|
||||||
|
for i in (0..length).rev() {
|
||||||
|
for j in i + 1..length {
|
||||||
|
dp[i][j] = (s[i] == s[j]) && dp[i + 1][j - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::dfs(&s, 0, &mut dp, &mut current, &mut result);
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dfs(
|
||||||
|
s: &Vec<char>,
|
||||||
|
pos: usize,
|
||||||
|
dp: &mut Vec<Vec<bool>>,
|
||||||
|
current: &mut Vec<String>,
|
||||||
|
result: &mut Vec<Vec<String>>,
|
||||||
|
) {
|
||||||
|
if pos >= s.len() {
|
||||||
|
result.push(current.clone());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in pos..s.len() {
|
||||||
|
if dp[pos][i] {
|
||||||
|
current.push(s[pos..i + 1].iter().collect());
|
||||||
|
Self::dfs(s, i + 1, dp, current, result);
|
||||||
|
current.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_131() {
|
||||||
|
assert_eq!(
|
||||||
|
vec![vec_string!("a", "a", "b"), vec_string!("aa", "b")],
|
||||||
|
Solution::partition("aab".to_owned())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
50
src/problem/p1328_break_a_palindrome.rs
Normal file
50
src/problem/p1328_break_a_palindrome.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* [1328] Break a Palindrome
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn break_palindrome(palindrome: String) -> String {
|
||||||
|
if palindrome.len() == 1 {
|
||||||
|
return "".to_owned();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut s: Vec<char> = palindrome.chars().collect();
|
||||||
|
|
||||||
|
let mut flag = false;
|
||||||
|
for i in 0..s.len() / 2 {
|
||||||
|
if s[i] != 'a' {
|
||||||
|
s[i] = 'a';
|
||||||
|
flag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 说明s的前半段全部都是a
|
||||||
|
// 直接把最后一个字符改成b
|
||||||
|
if !flag {
|
||||||
|
let pos = s.len() - 1;
|
||||||
|
s[pos] = 'b';
|
||||||
|
}
|
||||||
|
|
||||||
|
s.into_iter().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1328() {
|
||||||
|
assert_eq!("aabab", Solution::break_palindrome("aabaa".to_owned()));
|
||||||
|
assert_eq!("ab", Solution::break_palindrome("aa".to_owned()));
|
||||||
|
assert_eq!("ab", Solution::break_palindrome("bb".to_owned()));
|
||||||
|
assert_eq!("aaccba", Solution::break_palindrome("abccba".to_owned()));
|
||||||
|
assert_eq!("", Solution::break_palindrome("a".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
51
src/problem/p132_palindrome_partitioning_ii.rs
Normal file
51
src/problem/p132_palindrome_partitioning_ii.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* [132] Palindrome Partitioning II
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn min_cut(s: String) -> i32 {
|
||||||
|
let s: Vec<char> = s.chars().collect();
|
||||||
|
let length = s.len();
|
||||||
|
|
||||||
|
let mut palindorme = vec![vec![true; length]; length];
|
||||||
|
|
||||||
|
for i in (0..length).rev() {
|
||||||
|
for j in i + 1..length {
|
||||||
|
palindorme[i][j] = (s[i] == s[j]) && palindorme[i + 1][j - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut dp = vec![i32::MAX; length];
|
||||||
|
|
||||||
|
for i in 0..length {
|
||||||
|
if palindorme[0][i] {
|
||||||
|
dp[i] = 0;
|
||||||
|
} else {
|
||||||
|
for j in 0..i {
|
||||||
|
if palindorme[j + 1][i] {
|
||||||
|
dp[i] = dp[i].min(dp[j] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dp[length - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_132() {
|
||||||
|
assert_eq!(1, Solution::min_cut("aab".to_owned()));
|
||||||
|
assert_eq!(0, Solution::min_cut("a".to_owned()));
|
||||||
|
assert_eq!(1, Solution::min_cut("ab".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
49
src/problem/p1399_count_largest_group.rs
Normal file
49
src/problem/p1399_count_largest_group.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* [1399] Count Largest Group
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_largest_group(n: i32) -> i32 {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
(1..=n)
|
||||||
|
.into_iter()
|
||||||
|
.map(|mut x| {
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
while x > 0 {
|
||||||
|
result += x % 10;
|
||||||
|
x = x / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
})
|
||||||
|
.fold(&mut map, |map, i| {
|
||||||
|
let entry = map.entry(i).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
|
||||||
|
map
|
||||||
|
});
|
||||||
|
|
||||||
|
let max_count = map.values().max().unwrap();
|
||||||
|
map.values().filter(|x| x == &max_count).count() as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1399() {
|
||||||
|
assert_eq!(4, Solution::count_largest_group(13));
|
||||||
|
assert_eq!(2, Solution::count_largest_group(2));
|
||||||
|
assert_eq!(6, Solution::count_largest_group(15));
|
||||||
|
assert_eq!(5, Solution::count_largest_group(24));
|
||||||
|
}
|
||||||
|
}
|
87
src/problem/p1472_design_browser_history.rs
Normal file
87
src/problem/p1472_design_browser_history.rs
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/**
|
||||||
|
* [1472] Design Browser History
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
struct BrowserHistory {
|
||||||
|
history: Vec<String>,
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `&self` means the method takes an immutable reference.
|
||||||
|
* If you need a mutable reference, change it to `&mut self` instead.
|
||||||
|
*/
|
||||||
|
impl BrowserHistory {
|
||||||
|
fn new(homepage: String) -> Self {
|
||||||
|
Self {
|
||||||
|
history: vec![homepage],
|
||||||
|
pos: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit(&mut self, url: String) {
|
||||||
|
// 删除前向的所有网站
|
||||||
|
for _ in self.pos + 1..self.history.len() {
|
||||||
|
self.history.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.history.push(url);
|
||||||
|
self.pos += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn back(&mut self, steps: i32) -> String {
|
||||||
|
let steps = steps as usize;
|
||||||
|
if steps > self.pos {
|
||||||
|
self.pos = 0;
|
||||||
|
} else {
|
||||||
|
self.pos -= steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.history[self.pos].clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn forward(&mut self, steps: i32) -> String {
|
||||||
|
let steps = steps as usize;
|
||||||
|
if steps + self.pos >= self.history.len() {
|
||||||
|
self.pos = self.history.len() - 1;
|
||||||
|
} else {
|
||||||
|
self.pos += steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.history[self.pos].clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Your BrowserHistory object will be instantiated and called as such:
|
||||||
|
* let obj = BrowserHistory::new(homepage);
|
||||||
|
* obj.visit(url);
|
||||||
|
* let ret_2: String = obj.back(steps);
|
||||||
|
* let ret_3: String = obj.forward(steps);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1472() {
|
||||||
|
let mut history = BrowserHistory::new("leetcode.com".to_owned());
|
||||||
|
|
||||||
|
history.visit("google.com".to_owned());
|
||||||
|
history.visit("facebook.com".to_owned());
|
||||||
|
history.visit("youtube.com".to_owned());
|
||||||
|
assert_eq!("facebook.com", history.back(1));
|
||||||
|
assert_eq!("google.com", history.back(1));
|
||||||
|
assert_eq!("facebook.com", history.forward(1));
|
||||||
|
history.visit("linkedin.com".to_owned());
|
||||||
|
assert_eq!("linkedin.com", history.forward(2));
|
||||||
|
assert_eq!("google.com", history.back(2));
|
||||||
|
assert_eq!("leetcode.com", history.back(7));
|
||||||
|
}
|
||||||
|
}
|
54
src/problem/p1534_count_good_triplets.rs
Normal file
54
src/problem/p1534_count_good_triplets.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
* [1534] Count Good Triplets
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_good_triplets(arr: Vec<i32>, a: i32, b: i32, c: i32) -> i32 {
|
||||||
|
let mut result = 0;
|
||||||
|
let (a, b, c) = (a as u32, b as u32, c as u32);
|
||||||
|
|
||||||
|
for i in 0..arr.len() {
|
||||||
|
for j in i + 1..arr.len() {
|
||||||
|
for k in j + 1..arr.len() {
|
||||||
|
if arr[i].abs_diff(arr[j]) > a {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if arr[j].abs_diff(arr[k]) > b {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if arr[i].abs_diff(arr[k]) > c {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1534() {
|
||||||
|
assert_eq!(
|
||||||
|
4,
|
||||||
|
Solution::count_good_triplets(vec![3, 0, 1, 1, 9, 7], 7, 2, 3)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
0,
|
||||||
|
Solution::count_good_triplets(vec![1, 1, 2, 2, 3], 0, 0, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
71
src/problem/p1656_design_an_ordered_stream.rs
Normal file
71
src/problem/p1656_design_an_ordered_stream.rs
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* [1656] Design an Ordered Stream
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
struct OrderedStream {
|
||||||
|
array: Vec<Option<String>>,
|
||||||
|
pointer: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `&self` means the method takes an immutable reference.
|
||||||
|
* If you need a mutable reference, change it to `&mut self` instead.
|
||||||
|
*/
|
||||||
|
impl OrderedStream {
|
||||||
|
fn new(n: i32) -> Self {
|
||||||
|
let n = n as usize;
|
||||||
|
|
||||||
|
Self {
|
||||||
|
array: vec![None; n],
|
||||||
|
pointer: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert(&mut self, id_key: i32, value: String) -> Vec<String> {
|
||||||
|
let id = id_key as usize - 1;
|
||||||
|
|
||||||
|
self.array[id] = Some(value);
|
||||||
|
|
||||||
|
let mut result = vec![];
|
||||||
|
let mut pointer = self.pointer;
|
||||||
|
|
||||||
|
while pointer <= self.array.len() {
|
||||||
|
if let Some(item) = &self.array[pointer - 1] {
|
||||||
|
result.push(item.clone());
|
||||||
|
pointer += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.pointer = pointer;
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Your OrderedStream object will be instantiated and called as such:
|
||||||
|
* let obj = OrderedStream::new(n);
|
||||||
|
* let ret_1: Vec<String> = obj.insert(idKey, value);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1656() {
|
||||||
|
let mut stream = OrderedStream::new(5);
|
||||||
|
|
||||||
|
assert_eq!(Vec::<&str>::new(), stream.insert(3, "ccccc".to_owned()));
|
||||||
|
assert_eq!(vec!["aaaaa"], stream.insert(1, "aaaaa".to_owned()));
|
||||||
|
assert_eq!(vec!["bbbbb", "ccccc"], stream.insert(2, "bbbbb".to_owned()));
|
||||||
|
assert_eq!(Vec::<&str>::new(), stream.insert(5, "eeeee".to_owned()));
|
||||||
|
assert_eq!(vec!["ddddd", "eeeee"], stream.insert(4, "ddddd".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
46
src/problem/p1745_palindrome_partitioning_iv.rs
Normal file
46
src/problem/p1745_palindrome_partitioning_iv.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* [1745] Palindrome Partitioning IV
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn check_partitioning(s: String) -> bool {
|
||||||
|
let s = s.as_bytes();
|
||||||
|
let length = s.len();
|
||||||
|
|
||||||
|
let mut palindrome = vec![vec![true; length]; length];
|
||||||
|
|
||||||
|
for span in 2..=length {
|
||||||
|
for i in 0..=length - span {
|
||||||
|
let j = i + span - 1;
|
||||||
|
palindrome[i][j] = palindrome[i + 1][j - 1] && (s[i] == s[j])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..length - 2 {
|
||||||
|
// 所有字符串都必须是非空的
|
||||||
|
for j in i + 2..length {
|
||||||
|
if palindrome[0][i] && palindrome[i + 1][j - 1] && palindrome[j][length - 1] {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1745() {
|
||||||
|
assert!(Solution::check_partitioning("abcbdd".to_owned()));
|
||||||
|
assert!(!Solution::check_partitioning("bcbddxy".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
43
src/problem/p1863_sum_of_all_subset_xor_totals.rs
Normal file
43
src/problem/p1863_sum_of_all_subset_xor_totals.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* [1863] Sum of All Subset XOR Totals
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn subset_xor_sum(nums: Vec<i32>) -> i32 {
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
Self::search(0, 0, &nums, &mut result);
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search(mut sum: i32, i: usize, nums: &Vec<i32>, result: &mut i32) {
|
||||||
|
if i == nums.len() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不选择i
|
||||||
|
Self::search(sum, i + 1, nums, result);
|
||||||
|
// 选择i
|
||||||
|
sum = sum ^ nums[i];
|
||||||
|
*result += sum;
|
||||||
|
Self::search(sum, i + 1, nums, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1863() {
|
||||||
|
assert_eq!(6, Solution::subset_xor_sum(vec![1, 3]));
|
||||||
|
assert_eq!(28, Solution::subset_xor_sum(vec![5, 1, 6]));
|
||||||
|
assert_eq!(480, Solution::subset_xor_sum(vec![3, 4, 5, 6, 7, 8]));
|
||||||
|
}
|
||||||
|
}
|
49
src/problem/p1922_count_good_numbers.rs
Normal file
49
src/problem/p1922_count_good_numbers.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* [1922] Count Good Numbers
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
const MOD: i64 = 1_000_000_000 + 7;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_good_numbers(n: i64) -> i32 {
|
||||||
|
let mut result = Self::quick_power(20, n / 2);
|
||||||
|
|
||||||
|
if n % 2 == 1 {
|
||||||
|
result = result * 5 % MOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
result as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn quick_power(mut m: i64, mut n: i64) -> i64 {
|
||||||
|
let mut result = 1;
|
||||||
|
|
||||||
|
while n > 0 {
|
||||||
|
if n & 1 == 1 {
|
||||||
|
result = result * m % MOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
m = m * m % MOD;
|
||||||
|
n = n >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1922() {
|
||||||
|
assert_eq!(5, Solution::count_good_numbers(1));
|
||||||
|
assert_eq!(400, Solution::count_good_numbers(4));
|
||||||
|
assert_eq!(564_908_303, Solution::count_good_numbers(50));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* [1963] Minimum Number of Swaps to Make the String Balanced
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn min_swaps(s: String) -> i32 {
|
||||||
|
let mut count = 0;
|
||||||
|
let mut min_count = 0;
|
||||||
|
|
||||||
|
for c in s.chars() {
|
||||||
|
match c {
|
||||||
|
'[' => count += 1,
|
||||||
|
']' => {
|
||||||
|
count -= 1;
|
||||||
|
min_count = min_count.min(count)
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(-min_count + 1) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1963() {
|
||||||
|
assert_eq!(1, Solution::min_swaps("][][".to_owned()));
|
||||||
|
assert_eq!(2, Solution::min_swaps("]]][[[".to_owned()));
|
||||||
|
assert_eq!(0, Solution::min_swaps("[]".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
48
src/problem/p2012_sum_of_beauty_in_the_array.rs
Normal file
48
src/problem/p2012_sum_of_beauty_in_the_array.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* [2012] Sum of Beauty in the Array
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn sum_of_beauties(nums: Vec<i32>) -> i32 {
|
||||||
|
let n = nums.len();
|
||||||
|
let mut prefix = vec![0; n];
|
||||||
|
let mut suffix = vec![i32::MAX; n];
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
if i > 0 {
|
||||||
|
prefix[i] = prefix[i - 1].max(nums[i - 1]);
|
||||||
|
suffix[n - i - 1] = suffix[n - i].min(nums[n - i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(1..n - 1)
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| {
|
||||||
|
if nums[x] > prefix[x] && nums[x] < suffix[x] {
|
||||||
|
2
|
||||||
|
} else if nums[x] > nums[x - 1] && nums[x] < nums[x + 1] {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2012() {
|
||||||
|
assert_eq!(1, Solution::sum_of_beauties(vec![2, 4, 6, 4]));
|
||||||
|
assert_eq!(2, Solution::sum_of_beauties(vec![1, 2, 3]));
|
||||||
|
assert_eq!(0, Solution::sum_of_beauties(vec![3, 2, 1]));
|
||||||
|
}
|
||||||
|
}
|
72
src/problem/p2070_most_beautiful_item_for_each_query.rs
Normal file
72
src/problem/p2070_most_beautiful_item_for_each_query.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* [2070] Most Beautiful Item for Each Query
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn maximum_beauty(items: Vec<Vec<i32>>, queries: Vec<i32>) -> Vec<i32> {
|
||||||
|
let mut price_map = BTreeMap::new();
|
||||||
|
|
||||||
|
for item in items.iter() {
|
||||||
|
let entry = price_map.entry(item[0] as usize).or_insert(0);
|
||||||
|
*entry = (*entry).max(item[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut query_map: BTreeMap<usize, i32> = BTreeMap::new();
|
||||||
|
let mut result = Vec::with_capacity(queries.len());
|
||||||
|
|
||||||
|
for price in queries {
|
||||||
|
let price = price as usize;
|
||||||
|
let (min_price, mut min_result) = match query_map.range(..=price).last() {
|
||||||
|
Some((&p, &r)) => (p, r),
|
||||||
|
None => (0, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
if min_price == price {
|
||||||
|
result.push(min_result);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (&p, &r) in price_map.range(min_price + 1..=price) {
|
||||||
|
min_result = min_result.max(r);
|
||||||
|
query_map.insert(p, min_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push(min_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2070() {
|
||||||
|
assert_eq!(
|
||||||
|
vec![2, 4, 5, 5, 6, 6],
|
||||||
|
Solution::maximum_beauty(
|
||||||
|
vec![vec![1, 2], vec![3, 2], vec![2, 4], vec![5, 6], vec![3, 5]],
|
||||||
|
vec![1, 2, 3, 4, 5, 6]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
vec![4],
|
||||||
|
Solution::maximum_beauty(
|
||||||
|
vec![vec![1, 2], vec![1, 2], vec![1, 3], vec![1, 4]],
|
||||||
|
vec![1]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
vec![0],
|
||||||
|
Solution::maximum_beauty(vec![vec![10, 1000]], vec![5])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
85
src/problem/p2080_range_frequency_queries.rs
Normal file
85
src/problem/p2080_range_frequency_queries.rs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* [2080] Range Frequency Queries
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
struct RangeFreqQuery {
|
||||||
|
frequency_map: HashMap<i32, Vec<usize>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `&self` means the method takes an immutable reference.
|
||||||
|
* If you need a mutable reference, change it to `&mut self` instead.
|
||||||
|
*/
|
||||||
|
impl RangeFreqQuery {
|
||||||
|
fn new(arr: Vec<i32>) -> Self {
|
||||||
|
let mut frequency_map = HashMap::new();
|
||||||
|
|
||||||
|
for (i, v) in arr.into_iter().enumerate() {
|
||||||
|
let entry = frequency_map.entry(v).or_insert(vec![]);
|
||||||
|
entry.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self { frequency_map }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn query(&self, left: i32, right: i32, value: i32) -> i32 {
|
||||||
|
let (left, right) = (left as usize, right as usize);
|
||||||
|
|
||||||
|
if let Some(index) = self.frequency_map.get(&value) {
|
||||||
|
let l = index.binary_search(&left);
|
||||||
|
let r = index.binary_search(&right);
|
||||||
|
|
||||||
|
let result = match l {
|
||||||
|
Ok(l_ok) => match r {
|
||||||
|
Ok(r_ok) => r_ok - l_ok + 1,
|
||||||
|
Err(r_err) => r_err - l_ok,
|
||||||
|
},
|
||||||
|
Err(l_err) => match r {
|
||||||
|
Ok(r_ok) => r_ok - l_err + 1,
|
||||||
|
Err(r_err) => r_err - l_err,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result as i32
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Your RangeFreqQuery object will be instantiated and called as such:
|
||||||
|
* let obj = RangeFreqQuery::new(arr);
|
||||||
|
* let ret_1: i32 = obj.query(left, right, value);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2080() {
|
||||||
|
let query = RangeFreqQuery::new(vec![12, 33, 4, 56, 22, 2, 34, 33, 22, 12, 34, 56]);
|
||||||
|
|
||||||
|
assert_eq!(1, query.query(1, 2, 4));
|
||||||
|
assert_eq!(2, query.query(0, 11, 33));
|
||||||
|
|
||||||
|
let query = RangeFreqQuery::new(vec![2, 2, 1, 2, 2]);
|
||||||
|
|
||||||
|
// [2]
|
||||||
|
assert_eq!(1, query.query(2, 4, 1));
|
||||||
|
assert_eq!(1, query.query(1, 3, 1));
|
||||||
|
assert_eq!(1, query.query(0, 2, 1));
|
||||||
|
|
||||||
|
let query = RangeFreqQuery::new(vec![1, 1, 1, 2, 2]);
|
||||||
|
|
||||||
|
// [0, 1, 2]
|
||||||
|
assert_eq!(1, query.query(2, 2, 1));
|
||||||
|
}
|
||||||
|
}
|
50
src/problem/p2109_adding_spaces_to_a_string.rs
Normal file
50
src/problem/p2109_adding_spaces_to_a_string.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* [2109] Adding Spaces to a String
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn add_spaces(s: String, spaces: Vec<i32>) -> String {
|
||||||
|
let s: Vec<char> = s.chars().collect();
|
||||||
|
let mut result = Vec::with_capacity(s.len() + spaces.len());
|
||||||
|
let mut iter = spaces.into_iter().peekable();
|
||||||
|
|
||||||
|
for (i, v) in s.into_iter().enumerate() {
|
||||||
|
if let Some(&pos) = iter.peek() {
|
||||||
|
if i == pos as usize {
|
||||||
|
iter.next();
|
||||||
|
result.push(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.into_iter().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2109() {
|
||||||
|
assert_eq!(
|
||||||
|
"Leetcode Helps Me Learn",
|
||||||
|
Solution::add_spaces("LeetcodeHelpsMeLearn".to_owned(), vec![8, 13, 15])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"i code in py thon",
|
||||||
|
Solution::add_spaces("icodeinpython".to_owned(), vec![1, 5, 7, 9])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
" s p a c i n g",
|
||||||
|
Solution::add_spaces("spacing".to_owned(), vec![0, 1, 2, 3, 4, 5, 6])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* [2116] Check if a Parentheses String Can Be Valid
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn can_be_valid(s: String, locked: String) -> bool {
|
||||||
|
let s: Vec<u8> = s.bytes().collect();
|
||||||
|
let locked: Vec<bool> = locked
|
||||||
|
.bytes()
|
||||||
|
.map(|x| if x == b'0' { false } else { true })
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if s.len() % 2 != 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut locked_left = vec![];
|
||||||
|
let mut unlocked_pos = vec![];
|
||||||
|
|
||||||
|
for (i, &v) in s.iter().enumerate() {
|
||||||
|
if !locked[i] {
|
||||||
|
unlocked_pos.push(i);
|
||||||
|
} else {
|
||||||
|
if v == b'(' {
|
||||||
|
locked_left.push(i);
|
||||||
|
} else {
|
||||||
|
// 首先使用锁定的左括号匹配
|
||||||
|
if locked_left.pop().is_none() {
|
||||||
|
// 然后使用未锁定的位置修改
|
||||||
|
if unlocked_pos.pop().is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断剩余的未锁定位置和锁定的左括号是否匹配
|
||||||
|
while let Some(left_pos) = locked_left.pop() {
|
||||||
|
if let Some(unlock_pos) = unlocked_pos.pop() {
|
||||||
|
if left_pos > unlock_pos {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 剩余的未锁定括号必须是偶数个
|
||||||
|
unlocked_pos.len() % 2 == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2116() {
|
||||||
|
assert!(!Solution::can_be_valid(
|
||||||
|
"(((())".to_owned(),
|
||||||
|
"111111".to_owned()
|
||||||
|
));
|
||||||
|
assert!(Solution::can_be_valid(
|
||||||
|
"))()))".to_owned(),
|
||||||
|
"010100".to_owned()
|
||||||
|
));
|
||||||
|
assert!(Solution::can_be_valid("()()".to_owned(), "0000".to_owned()));
|
||||||
|
assert!(!Solution::can_be_valid(")".to_owned(), "0".to_owned()));
|
||||||
|
assert!(Solution::can_be_valid(
|
||||||
|
"(((())(((())".to_owned(),
|
||||||
|
"111111010111".to_owned()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
56
src/problem/p2140_solving_questions_with_brainpower.rs
Normal file
56
src/problem/p2140_solving_questions_with_brainpower.rs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* [2140] Solving Questions With Brainpower
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn most_points(questions: Vec<Vec<i32>>) -> i64 {
|
||||||
|
let questions: Vec<(i64, usize)> = questions
|
||||||
|
.into_iter()
|
||||||
|
.map(|a| (a[0] as i64, a[1] as usize))
|
||||||
|
.collect();
|
||||||
|
let n = questions.len();
|
||||||
|
let mut dp = vec![0; n];
|
||||||
|
|
||||||
|
for i in (0..n).rev() {
|
||||||
|
let (score, brain_power) = questions[i];
|
||||||
|
dp[i] = if i == n - 1 { 0 } else { dp[i + 1] };
|
||||||
|
|
||||||
|
// 选择做i题就需要跳过brian_power道题
|
||||||
|
if i + brain_power + 1 < n {
|
||||||
|
dp[i] = dp[i].max(dp[i + brain_power + 1] + score);
|
||||||
|
} else {
|
||||||
|
dp[i] = dp[i].max(score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dp[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2140() {
|
||||||
|
assert_eq!(
|
||||||
|
5,
|
||||||
|
Solution::most_points(vec![vec![3, 2], vec![4, 3], vec![4, 4], vec![2, 5]])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
7,
|
||||||
|
Solution::most_points(vec![
|
||||||
|
vec![1, 1],
|
||||||
|
vec![2, 2],
|
||||||
|
vec![3, 3],
|
||||||
|
vec![4, 4],
|
||||||
|
vec![5, 5]
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
45
src/problem/p2145_count_the_hidden_sequences.rs
Normal file
45
src/problem/p2145_count_the_hidden_sequences.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* [2145] Count the Hidden Sequences
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn number_of_arrays(differences: Vec<i32>, lower: i32, upper: i32) -> i32 {
|
||||||
|
let mut min_value = 0i64;
|
||||||
|
let mut max_value = 0i64;
|
||||||
|
let mut last_value = 0i64;
|
||||||
|
|
||||||
|
for i in differences.into_iter() {
|
||||||
|
let value = last_value + i as i64;
|
||||||
|
min_value = min_value.min(value);
|
||||||
|
max_value = max_value.max(value);
|
||||||
|
last_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
let range = max_value - min_value;
|
||||||
|
|
||||||
|
let result = (upper - lower + 1) as i64 - range;
|
||||||
|
if result > 0 {
|
||||||
|
result as i32
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2145() {
|
||||||
|
assert_eq!(60, Solution::number_of_arrays(vec![-40], -46, 53));
|
||||||
|
assert_eq!(2, Solution::number_of_arrays(vec![1, -3, 4], 1, 6));
|
||||||
|
assert_eq!(4, Solution::number_of_arrays(vec![3, -4, 5, 1, -2], -4, 5));
|
||||||
|
assert_eq!(0, Solution::number_of_arrays(vec![4, -7, 2], 3, 6));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* [2176] Count Equal and Divisible Pairs in an Array
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_pairs(nums: Vec<i32>, k: i32) -> i32 {
|
||||||
|
let k = k as usize;
|
||||||
|
let n = nums.len();
|
||||||
|
|
||||||
|
(0..n)
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| (x + 1..n).into_iter().map(move |y| (x, y)))
|
||||||
|
.flatten()
|
||||||
|
.filter_map(|(i, j)| {
|
||||||
|
if nums[i] == nums[j] && i * j % k == 0 {
|
||||||
|
Some(())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.count() as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2176() {
|
||||||
|
assert_eq!(4, Solution::count_pairs(vec![3, 1, 2, 2, 2, 1, 3], 2));
|
||||||
|
assert_eq!(0, Solution::count_pairs(vec![1, 2, 3, 4], 1));
|
||||||
|
}
|
||||||
|
}
|
99
src/problem/p2179_count_good_triplets_in_an_array.rs
Normal file
99
src/problem/p2179_count_good_triplets_in_an_array.rs
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/**
|
||||||
|
* [2179] Count Good Triplets in an Array
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
struct FenwickTree {
|
||||||
|
tree: Vec<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FenwickTree {
|
||||||
|
fn new(size: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
tree: vec![0; size + 1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, mut index: usize, delta: i64) {
|
||||||
|
index += 1;
|
||||||
|
|
||||||
|
while index < self.tree.len() {
|
||||||
|
self.tree[index] += delta;
|
||||||
|
|
||||||
|
index += Self::low_bit(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn query(&self, mut index: usize) -> i64 {
|
||||||
|
index += 1;
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
while index > 0 {
|
||||||
|
result += self.tree[index];
|
||||||
|
index -= Self::low_bit(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
// 二进制最低位1以及后面的0组成的数
|
||||||
|
fn low_bit(i: usize) -> usize {
|
||||||
|
i & (!i + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn good_triplets(nums1: Vec<i32>, nums2: Vec<i32>) -> i64 {
|
||||||
|
let n = nums1.len();
|
||||||
|
// nums2中各个值到下标的映射数组
|
||||||
|
let mut pos2 = vec![0; n];
|
||||||
|
// index_mapping 是nums1中一个数在nums2中的下标
|
||||||
|
// reverse_index_mapping是该下标同nums1中数字下标的对应关系
|
||||||
|
let mut reversed_index_mapping = vec![0; n];
|
||||||
|
|
||||||
|
for (i, v) in nums2.iter().enumerate() {
|
||||||
|
pos2[*v as usize] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
// nums1中的一个值在nums2中的下标到该值在nums1中的下标的映射
|
||||||
|
reversed_index_mapping[pos2[nums1[i] as usize]] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tree = FenwickTree::new(n);
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
// 枚举num1s中的一个值在nums2中的下标
|
||||||
|
for j in 0..n {
|
||||||
|
let pos = reversed_index_mapping[j];
|
||||||
|
let left = tree.query(pos);
|
||||||
|
tree.update(pos, 1);
|
||||||
|
let right = ((n - 1 - pos) - (j - left as usize)) as i64;
|
||||||
|
result += left * right;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2179() {
|
||||||
|
assert_eq!(
|
||||||
|
1,
|
||||||
|
Solution::good_triplets(vec![2, 0, 1, 3], vec![0, 1, 2, 3])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
4,
|
||||||
|
Solution::good_triplets(vec![4, 0, 1, 3, 2], vec![4, 1, 0, 2, 3])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
use std::ffi::FromVecWithNulError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [2209] Minimum White Tiles After Covering With Carpets
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn minimum_white_tiles(floor: String, num_carpets: i32, carpet_len: i32) -> i32 {
|
||||||
|
let carpets_num = num_carpets as usize;
|
||||||
|
let carpet_length = carpet_len as usize;
|
||||||
|
let floor: Vec<bool> = floor
|
||||||
|
.chars()
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| if x == '0' { true } else { false })
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// dp[i][j] 表示
|
||||||
|
// 当使用j块地毯时
|
||||||
|
// [i..] 还有多少白色的地砖没有被覆盖
|
||||||
|
let mut dp = vec![vec![0; carpets_num + 1]; floor.len()];
|
||||||
|
|
||||||
|
// 初始化dp[i][0]
|
||||||
|
let mut white_count = 0;
|
||||||
|
for i in (0..floor.len()).rev() {
|
||||||
|
if !floor[i] {
|
||||||
|
white_count += 1;
|
||||||
|
}
|
||||||
|
dp[i][0] = white_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in (0..floor.len() - 1).rev() {
|
||||||
|
for j in 1..=carpets_num {
|
||||||
|
// 在floor[i]处不放置地毯
|
||||||
|
let a = dp[i + 1][j] + if !floor[i] { 1 } else { 0 };
|
||||||
|
// 在floor[i]处放置地毯
|
||||||
|
// 如果放置的长度超过地板的总长
|
||||||
|
// 则剩余的白色地砖数量必然为0
|
||||||
|
let b = if i + carpet_length >= floor.len() {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
dp[i + carpet_length][j - 1]
|
||||||
|
};
|
||||||
|
dp[i][j] = a.min(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dp[0][carpets_num]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2209() {
|
||||||
|
assert_eq!(0, Solution::minimum_white_tiles("11111".to_owned(), 2, 3));
|
||||||
|
assert_eq!(
|
||||||
|
2,
|
||||||
|
Solution::minimum_white_tiles("10110101".to_owned(), 2, 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
78
src/problem/p2234_maximum_total_beauty_of_the_gardens.rs
Normal file
78
src/problem/p2234_maximum_total_beauty_of_the_gardens.rs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* [2234] Maximum Total Beauty of the Gardens
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn maximum_beauty(
|
||||||
|
mut flowers: Vec<i32>,
|
||||||
|
new_flowers: i64,
|
||||||
|
target: i32,
|
||||||
|
full: i32,
|
||||||
|
partial: i32,
|
||||||
|
) -> i64 {
|
||||||
|
let n = flowers.len();
|
||||||
|
let target = target as i64;
|
||||||
|
let full = full as i64;
|
||||||
|
let partial = partial as i64;
|
||||||
|
|
||||||
|
let mut flowers: Vec<i64> = flowers
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| (x as i64).min(target))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
flowers.sort_unstable_by(|a, b| b.cmp(a));
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
let mut sum: i64 = flowers.iter().map(|x| *x).sum();
|
||||||
|
if target * n as i64 - sum <= new_flowers {
|
||||||
|
result += full * n as i64;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut prefix = 0;
|
||||||
|
let mut ptr = 0;
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
if i != 0 {
|
||||||
|
prefix += flowers[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if flowers[i] == target {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rest = new_flowers - (target * i as i64 - prefix);
|
||||||
|
if rest < 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while !(ptr >= i && flowers[ptr] * (n - ptr) as i64 - sum <= rest) {
|
||||||
|
sum -= flowers[ptr];
|
||||||
|
ptr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rest -= flowers[ptr] * (n - ptr) as i64 - sum;
|
||||||
|
result = result.max(
|
||||||
|
full * i as i64
|
||||||
|
+ partial * (flowers[ptr] + rest / (n - ptr) as i64).min(target - 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2234() {
|
||||||
|
assert_eq!(14, Solution::maximum_beauty(vec![1, 3, 1, 1], 7, 6, 12, 1));
|
||||||
|
assert_eq!(30, Solution::maximum_beauty(vec![2, 4, 5, 3], 10, 5, 2, 6));
|
||||||
|
}
|
||||||
|
}
|
34
src/problem/p2255_count_prefixes_of_a_given_string.rs
Normal file
34
src/problem/p2255_count_prefixes_of_a_given_string.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* [2255] Count Prefixes of a Given String
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_prefixes(words: Vec<String>, s: String) -> i32 {
|
||||||
|
words.iter().filter(|i| s.starts_with(i.as_str())).count() as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2255() {
|
||||||
|
assert_eq!(
|
||||||
|
3,
|
||||||
|
Solution::count_prefixes(
|
||||||
|
vec_string!("a", "b", "c", "ab", "bc", "abc"),
|
||||||
|
"abc".to_owned()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
2,
|
||||||
|
Solution::count_prefixes(vec_string!("a", "a"), "aa".to_owned())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
36
src/problem/p2269_find_the_k_beauty_of_a_number.rs
Normal file
36
src/problem/p2269_find_the_k_beauty_of_a_number.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
* [2269] Find the K-Beauty of a Number
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn divisor_substrings(num: i32, k: i32) -> i32 {
|
||||||
|
let k = k as usize;
|
||||||
|
let num_str: Vec<char> = num.to_string().chars().collect();
|
||||||
|
|
||||||
|
(0..=num_str.len() - k)
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| {
|
||||||
|
(&num_str[i..i + k])
|
||||||
|
.iter()
|
||||||
|
.fold(0i32, |v, c| v * 10 + c.to_digit(10).unwrap() as i32)
|
||||||
|
})
|
||||||
|
.filter(|&v| v != 0 && num % v == 0)
|
||||||
|
.count() as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2269() {
|
||||||
|
assert_eq!(2, Solution::divisor_substrings(240, 2));
|
||||||
|
assert_eq!(2, Solution::divisor_substrings(430043, 2));
|
||||||
|
}
|
||||||
|
}
|
58
src/problem/p2272_substring_with_largest_variance.rs
Normal file
58
src/problem/p2272_substring_with_largest_variance.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* [2272] Substring With Largest Variance
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn largest_variance(s: String) -> i32 {
|
||||||
|
let word: Vec<char> = s.chars().collect();
|
||||||
|
let mut pos_map = HashMap::new();
|
||||||
|
|
||||||
|
for (i, c) in word.into_iter().enumerate() {
|
||||||
|
let entry = pos_map.entry(c).or_insert(vec![]);
|
||||||
|
entry.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
for (c0, pos0) in pos_map.iter() {
|
||||||
|
for (c1, pos1) in pos_map.iter() {
|
||||||
|
if c0 != c1 {
|
||||||
|
let (mut i, mut j) = (0, 0);
|
||||||
|
let (mut f, mut g) = (0, i32::MIN);
|
||||||
|
|
||||||
|
// 这里的算法类似于合并两个有序列表
|
||||||
|
while i < pos0.len() || j < pos1.len() {
|
||||||
|
if j == pos1.len() || (i < pos0.len() && pos0[i] < pos1[j]) {
|
||||||
|
(f, g) = (f.max(0) + 1, g + 1);
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
(f, g) = (f.max(0) - 1, f.max(g).max(0) - 1);
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = result.max(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2272() {
|
||||||
|
assert_eq!(3, Solution::largest_variance("aababbb".to_owned()));
|
||||||
|
assert_eq!(0, Solution::largest_variance("abcde".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
25
src/problem/p2278_percentage_of_letter_in_string.rs
Normal file
25
src/problem/p2278_percentage_of_letter_in_string.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
* [2278] Percentage of Letter in String
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn percentage_letter(s: String, letter: char) -> i32 {
|
||||||
|
(s.chars().filter(|c| *c == letter).count() * 100 / s.len()) as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2278() {
|
||||||
|
assert_eq!(33, Solution::percentage_letter("foobar".to_owned(), 'o'));
|
||||||
|
assert_eq!(0, Solution::percentage_letter("jjjj".to_owned(), 'k'));
|
||||||
|
}
|
||||||
|
}
|
81
src/problem/p2338_count_the_number_of_ideal_arrays.rs
Normal file
81
src/problem/p2338_count_the_number_of_ideal_arrays.rs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
* [2338] Count the Number of Ideal Arrays
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
const MOD: usize = 1_000_000_007;
|
||||||
|
const MAX_N: usize = 10010;
|
||||||
|
const MAX_P: usize = 15;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn ideal_arrays(n: i32, max_value: i32) -> i32 {
|
||||||
|
let mut result = 0usize;
|
||||||
|
let n = n as usize;
|
||||||
|
let (prime_sieves, dp) = Self::calculate_dp_array();
|
||||||
|
|
||||||
|
for x in 1..=max_value {
|
||||||
|
let mut current = 1;
|
||||||
|
for &p in prime_sieves[x as usize].iter() {
|
||||||
|
current = current * dp[n + p - 1][p] % MOD;
|
||||||
|
}
|
||||||
|
result = (result + current) % MOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
result as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_dp_array() -> (Vec<Vec<usize>>, Vec<Vec<usize>>) {
|
||||||
|
// 最小质因数列表
|
||||||
|
let mut sieves = vec![0; MAX_N];
|
||||||
|
|
||||||
|
for i in 2..MAX_N {
|
||||||
|
if sieves[i] == 0 {
|
||||||
|
for j in (i..MAX_N).step_by(i) {
|
||||||
|
sieves[j] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut prime_sieves = vec![vec![]; MAX_N];
|
||||||
|
for i in 2..MAX_N {
|
||||||
|
let mut x = i;
|
||||||
|
|
||||||
|
while x > 1 {
|
||||||
|
let p = sieves[x];
|
||||||
|
let mut current = 0;
|
||||||
|
while x % p == 0 {
|
||||||
|
x /= p;
|
||||||
|
current += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
prime_sieves[i].push(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut dp = vec![vec![0usize; MAX_P + 1]; MAX_N + MAX_P];
|
||||||
|
dp[0][0] = 1;
|
||||||
|
for i in 1..(MAX_N + MAX_P) {
|
||||||
|
dp[i][0] = 1;
|
||||||
|
for j in 1..(i.min(MAX_P) + 1) {
|
||||||
|
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1]) % MOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(prime_sieves, dp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2338() {
|
||||||
|
assert_eq!(10, Solution::ideal_arrays(2, 5));
|
||||||
|
assert_eq!(11, Solution::ideal_arrays(5, 3));
|
||||||
|
}
|
||||||
|
}
|
137
src/problem/p2353_design_a_food_rating_system.rs
Normal file
137
src/problem/p2353_design_a_food_rating_system.rs
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/**
|
||||||
|
* [2353] Design a Food Rating System
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::collections::{BinaryHeap, HashMap};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
struct Food {
|
||||||
|
name: String,
|
||||||
|
cuisine: String,
|
||||||
|
rating: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Food {
|
||||||
|
fn new(name: String, cuisine: String, rating: i32) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
cuisine,
|
||||||
|
rating,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_rating(&self, new_rating: i32) -> Self {
|
||||||
|
Self {
|
||||||
|
name: self.name.clone(),
|
||||||
|
cuisine: self.cuisine.clone(),
|
||||||
|
rating: new_rating,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Food {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
match self.rating.cmp(&other.rating) {
|
||||||
|
Ordering::Equal => other.name.cmp(&self.name),
|
||||||
|
a => a,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Food {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FoodRatings {
|
||||||
|
food_map: HashMap<String, Food>,
|
||||||
|
cuisine_heap: HashMap<String, BinaryHeap<Food>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `&self` means the method takes an immutable reference.
|
||||||
|
* If you need a mutable reference, change it to `&mut self` instead.
|
||||||
|
*/
|
||||||
|
impl FoodRatings {
|
||||||
|
fn new(foods: Vec<String>, cuisines: Vec<String>, ratings: Vec<i32>) -> Self {
|
||||||
|
let mut food_map = HashMap::new();
|
||||||
|
let mut cuisine_heap = HashMap::new();
|
||||||
|
|
||||||
|
for ((name, cuisine), &rating) in foods.iter().zip(cuisines.iter()).zip(ratings.iter()) {
|
||||||
|
food_map.insert(
|
||||||
|
name.clone(),
|
||||||
|
Food::new(name.clone(), cuisine.clone(), rating),
|
||||||
|
);
|
||||||
|
|
||||||
|
let heap = cuisine_heap
|
||||||
|
.entry(cuisine.clone())
|
||||||
|
.or_insert(BinaryHeap::new());
|
||||||
|
heap.push(Food::new(name.clone(), cuisine.clone(), rating.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
food_map,
|
||||||
|
cuisine_heap,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_rating(&mut self, food: String, new_rating: i32) {
|
||||||
|
let food_entry = self.food_map.get_mut(&food).unwrap();
|
||||||
|
food_entry.rating = new_rating;
|
||||||
|
|
||||||
|
let heap = self.cuisine_heap.get_mut(&food_entry.cuisine).unwrap();
|
||||||
|
heap.push(food_entry.update_rating(new_rating));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn highest_rated(&mut self, cuisine: String) -> String {
|
||||||
|
let heap = self.cuisine_heap.get_mut(&cuisine).unwrap();
|
||||||
|
|
||||||
|
while let Some(head) = heap.peek() {
|
||||||
|
let food_entry = self.food_map.get(&head.name).unwrap();
|
||||||
|
|
||||||
|
if head.rating == food_entry.rating {
|
||||||
|
return food_entry.name.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
heap.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
"".to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Your FoodRatings object will be instantiated and called as such:
|
||||||
|
* let obj = FoodRatings::new(foods, cuisines, ratings);
|
||||||
|
* obj.change_rating(food, newRating);
|
||||||
|
* let ret_2: String = obj.highest_rated(cuisine);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2353() {
|
||||||
|
let mut ratings = FoodRatings::new(
|
||||||
|
vec_string!("kimchi", "miso", "sushi", "moussaka", "ramen", "bulgogi"),
|
||||||
|
vec_string!("korean", "japanese", "japanese", "greek", "japanese", "korean"),
|
||||||
|
vec![9, 12, 8, 15, 14, 7],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!("kimchi", ratings.highest_rated("korean".to_owned()));
|
||||||
|
assert_eq!("ramen", ratings.highest_rated("japanese".to_owned()));
|
||||||
|
|
||||||
|
ratings.change_rating("sushi".to_owned(), 16);
|
||||||
|
assert_eq!("sushi", ratings.highest_rated("japanese".to_owned()));
|
||||||
|
|
||||||
|
ratings.change_rating("ramen".to_owned(), 16);
|
||||||
|
assert_eq!("ramen", ratings.highest_rated("japanese".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
55
src/problem/p2360_longest_cycle_in_a_graph.rs
Normal file
55
src/problem/p2360_longest_cycle_in_a_graph.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* [2360] Longest Cycle in a Graph
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn longest_cycle(edges: Vec<i32>) -> i32 {
|
||||||
|
let n = edges.len();
|
||||||
|
let mut labels = vec![0; n];
|
||||||
|
|
||||||
|
let mut current_label = 0;
|
||||||
|
let mut result = -1;
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
if labels[i] != 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut pos = i as i32;
|
||||||
|
let start_label = current_label;
|
||||||
|
|
||||||
|
while pos != -1 {
|
||||||
|
current_label += 1;
|
||||||
|
// 遇到已经遍历过的节点
|
||||||
|
let real_pos = pos as usize;
|
||||||
|
if labels[real_pos] != 0 {
|
||||||
|
if labels[real_pos] > start_label {
|
||||||
|
result = result.max(current_label - labels[real_pos]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
labels[real_pos] = current_label;
|
||||||
|
pos = edges[real_pos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2360() {
|
||||||
|
assert_eq!(3, Solution::longest_cycle(vec![3, 3, 4, 2, 3]));
|
||||||
|
assert_eq!(-1, Solution::longest_cycle(vec![2, -1, 3, 1]));
|
||||||
|
}
|
||||||
|
}
|
41
src/problem/p2364_count_number_of_bad_pairs.rs
Normal file
41
src/problem/p2364_count_number_of_bad_pairs.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* [2364] Count Number of Bad Pairs
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_bad_pairs(nums: Vec<i32>) -> i64 {
|
||||||
|
let n = nums.len() as i64;
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
|
for (i, v) in nums.into_iter().enumerate() {
|
||||||
|
let delta = v - i as i32;
|
||||||
|
let mut entry = map.entry(delta).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 反过来计算好数对的数量
|
||||||
|
let good_pair_count = map
|
||||||
|
.values()
|
||||||
|
.filter_map(|&v| if v >= 2 { Some(v * (v - 1) / 2) } else { None })
|
||||||
|
.sum::<i64>();
|
||||||
|
|
||||||
|
n * (n - 1) / 2 - good_pair_count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2364() {
|
||||||
|
assert_eq!(5, Solution::count_bad_pairs(vec![4, 1, 3, 3]));
|
||||||
|
assert_eq!(0, Solution::count_bad_pairs(vec![1, 2, 3, 4, 5]));
|
||||||
|
}
|
||||||
|
}
|
105
src/problem/p2502_design_memory_allocator.rs
Normal file
105
src/problem/p2502_design_memory_allocator.rs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/**
|
||||||
|
* [2502] Design Memory Allocator
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
struct Allocator {
|
||||||
|
memory: Vec<bool>,
|
||||||
|
id_map: HashMap<i32, Vec<(usize, usize)>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `&self` means the method takes an immutable reference.
|
||||||
|
* If you need a mutable reference, change it to `&mut self` instead.
|
||||||
|
*/
|
||||||
|
impl Allocator {
|
||||||
|
fn new(n: i32) -> Self {
|
||||||
|
let n = n as usize;
|
||||||
|
Self {
|
||||||
|
memory: vec![false; n],
|
||||||
|
id_map: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn allocate(&mut self, size: i32, m_id: i32) -> i32 {
|
||||||
|
let size = size as usize;
|
||||||
|
let mut start = 0;
|
||||||
|
|
||||||
|
while start < self.memory.len() {
|
||||||
|
let mut pos = start;
|
||||||
|
while pos < self.memory.len() && !self.memory[pos] {
|
||||||
|
if pos - start + 1 == size {
|
||||||
|
for i in start..=pos {
|
||||||
|
self.memory[i] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let entry = self.id_map.entry(m_id).or_insert(vec![]);
|
||||||
|
entry.push((start, pos));
|
||||||
|
return start as i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 到达这里只能说明找到的空间不足
|
||||||
|
start = pos + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn free_memory(&mut self, m_id: i32) -> i32 {
|
||||||
|
if let Some(array) = self.id_map.get(&m_id) {
|
||||||
|
let mut length = 0;
|
||||||
|
|
||||||
|
for &(start, end) in array.iter() {
|
||||||
|
for i in start..=end {
|
||||||
|
self.memory[i] = false;
|
||||||
|
}
|
||||||
|
length += (end - start + 1) as i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.id_map.remove(&m_id);
|
||||||
|
length
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Your Allocator object will be instantiated and called as such:
|
||||||
|
* let obj = Allocator::new(n);
|
||||||
|
* let ret_1: i32 = obj.allocate(size, mID);
|
||||||
|
* let ret_2: i32 = obj.free_memory(mID);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2502() {
|
||||||
|
let mut allocator = Allocator::new(10);
|
||||||
|
|
||||||
|
assert_eq!(0, allocator.allocate(1, 1));
|
||||||
|
assert_eq!(1, allocator.allocate(1, 2));
|
||||||
|
assert_eq!(2, allocator.allocate(1, 3));
|
||||||
|
|
||||||
|
assert_eq!(1, allocator.free_memory(2));
|
||||||
|
|
||||||
|
assert_eq!(3, allocator.allocate(3, 4));
|
||||||
|
assert_eq!(1, allocator.allocate(1, 1));
|
||||||
|
assert_eq!(6, allocator.allocate(1, 1));
|
||||||
|
|
||||||
|
assert_eq!(3, allocator.free_memory(1));
|
||||||
|
|
||||||
|
assert_eq!(-1, allocator.allocate(10, 2));
|
||||||
|
assert_eq!(0, allocator.free_memory(7));
|
||||||
|
}
|
||||||
|
}
|
50
src/problem/p2506_count_pairs_of_similar_strings.rs
Normal file
50
src/problem/p2506_count_pairs_of_similar_strings.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* [2506] Count Pairs Of Similar Strings
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn similar_pairs(words: Vec<String>) -> i32 {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
|
for word in words.iter() {
|
||||||
|
let mut bits = 0;
|
||||||
|
|
||||||
|
for c in word.chars() {
|
||||||
|
bits = bits | (1 << (c as u8 - 'a' as u8))
|
||||||
|
}
|
||||||
|
|
||||||
|
let entry = map.entry(bits).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
for &v in map.values() {
|
||||||
|
// C(n, 2)
|
||||||
|
result += v * (v - 1) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2506() {
|
||||||
|
assert_eq!(
|
||||||
|
2,
|
||||||
|
Solution::similar_pairs(vec_string!("aba", "aabb", "abcd", "bac", "aabc"))
|
||||||
|
);
|
||||||
|
assert_eq!(3, Solution::similar_pairs(vec_string!("aabb", "ab", "ba")));
|
||||||
|
assert_eq!(0, Solution::similar_pairs(vec_string!("nba", "cba", "dba")));
|
||||||
|
}
|
||||||
|
}
|
58
src/problem/p2537_count_the_number_of_good_subarrays.rs
Normal file
58
src/problem/p2537_count_the_number_of_good_subarrays.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* [2537] Count the Number of Good Subarrays
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_good(nums: Vec<i32>, k: i32) -> i64 {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
let n = nums.len();
|
||||||
|
|
||||||
|
let mut result = 0i64;
|
||||||
|
let mut count = 0;
|
||||||
|
let (mut left, mut right) = (0, 0);
|
||||||
|
|
||||||
|
while left < n {
|
||||||
|
while right < n && count < k {
|
||||||
|
let entry = map.entry(nums[right]).or_insert(0);
|
||||||
|
count += *entry;
|
||||||
|
*entry += 1;
|
||||||
|
|
||||||
|
right += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if count < k && right >= n {
|
||||||
|
// 拼尽全力无法战胜
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 此时已经遇到了一个合格的序列
|
||||||
|
// 注意序列可以多余的包含右侧的所有元素
|
||||||
|
result += (n - right) as i64 + 1;
|
||||||
|
|
||||||
|
// 右移left
|
||||||
|
let entry = map.entry(nums[left]).or_insert(0);
|
||||||
|
count -= *entry - 1;
|
||||||
|
*entry -= 1;
|
||||||
|
left += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2537() {
|
||||||
|
assert_eq!(4, Solution::count_good(vec![3, 1, 4, 3, 2, 2, 4], 2));
|
||||||
|
assert_eq!(1, Solution::count_good(vec![1, 1, 1, 1, 1], 10));
|
||||||
|
}
|
||||||
|
}
|
35
src/problem/p2563_count_the_number_of_fair_pairs.rs
Normal file
35
src/problem/p2563_count_the_number_of_fair_pairs.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* [2563] Count the Number of Fair Pairs
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_fair_pairs(mut nums: Vec<i32>, lower: i32, upper: i32) -> i64 {
|
||||||
|
nums.sort_unstable();
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
for i in 0..nums.len() {
|
||||||
|
let l = nums[0..i].partition_point(|&x| x + nums[i] < lower);
|
||||||
|
let r = nums[0..i].partition_point(|&x| x + nums[i] <= upper);
|
||||||
|
|
||||||
|
result += r - l;
|
||||||
|
}
|
||||||
|
|
||||||
|
result as i64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2563() {
|
||||||
|
assert_eq!(6, Solution::count_fair_pairs(vec![0, 1, 7, 4, 4, 5], 3, 6));
|
||||||
|
assert_eq!(1, Solution::count_fair_pairs(vec![1, 7, 9, 2, 5], 11, 11));
|
||||||
|
}
|
||||||
|
}
|
45
src/problem/p2588_count_the_number_of_beautiful_subarrays.rs
Normal file
45
src/problem/p2588_count_the_number_of_beautiful_subarrays.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* [2588] Count the Number of Beautiful Subarrays
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn beautiful_subarrays(nums: Vec<i32>) -> i64 {
|
||||||
|
let n = nums.len();
|
||||||
|
let mut prefix = vec![0; n + 1];
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
prefix[i + 1] = prefix[i] ^ nums[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
for i in 0..=n {
|
||||||
|
if let Some(count) = map.get(&prefix[i]) {
|
||||||
|
result += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
let entry = map.entry(prefix[i] ^ 0).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2588() {
|
||||||
|
assert_eq!(2, Solution::beautiful_subarrays(vec![4, 3, 1, 2, 4]));
|
||||||
|
assert_eq!(0, Solution::beautiful_subarrays(vec![1, 10, 4]));
|
||||||
|
}
|
||||||
|
}
|
43
src/problem/p2595_number_of_even_and_odd_bits.rs
Normal file
43
src/problem/p2595_number_of_even_and_odd_bits.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* [2595] Number of Even and Odd Bits
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn even_odd_bit(mut n: i32) -> Vec<i32> {
|
||||||
|
let mut is_even = true;
|
||||||
|
let mut even_count = 0;
|
||||||
|
let mut odd_count = 0;
|
||||||
|
|
||||||
|
while n > 0 {
|
||||||
|
let bit = n % 2;
|
||||||
|
if bit == 1 {
|
||||||
|
if is_even {
|
||||||
|
even_count += 1;
|
||||||
|
} else {
|
||||||
|
odd_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_even = !is_even;
|
||||||
|
n = n / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec![even_count, odd_count]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2595() {
|
||||||
|
assert_eq!(vec![1, 2], Solution::even_odd_bit(50));
|
||||||
|
assert_eq!(vec![0, 1], Solution::even_odd_bit(2));
|
||||||
|
}
|
||||||
|
}
|
64
src/problem/p2597_the_number_of_beautiful_subsets.rs
Normal file
64
src/problem/p2597_the_number_of_beautiful_subsets.rs
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* [2597] The Number of Beautiful Subsets
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn beautiful_subsets(nums: Vec<i32>, k: i32) -> i32 {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
|
for i in nums {
|
||||||
|
let value = i % k;
|
||||||
|
let entry = map.entry(value).or_insert(BTreeMap::new());
|
||||||
|
let group_entry = entry.entry(i).or_insert(0);
|
||||||
|
*group_entry += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = 1;
|
||||||
|
|
||||||
|
for group in map.values() {
|
||||||
|
let n = group.len();
|
||||||
|
// (x, y) x表示不选择第i个数
|
||||||
|
// y表示选择第i个数
|
||||||
|
let mut dp = vec![(0, 0); n];
|
||||||
|
// 懒得用迭代器移来移去
|
||||||
|
// 直接复制到数组开干
|
||||||
|
let array: Vec<(i32, i32)> = group.iter().map(|(x, y)| (*x, *y)).collect();
|
||||||
|
|
||||||
|
for (i, &(key, count)) in array.iter().enumerate() {
|
||||||
|
if i == 0 {
|
||||||
|
dp[0].0 = 1;
|
||||||
|
dp[0].1 = (1 << count) - 1;
|
||||||
|
} else {
|
||||||
|
dp[i].0 = dp[i - 1].0 + dp[i - 1].1;
|
||||||
|
|
||||||
|
if key - array[i - 1].0 == k {
|
||||||
|
dp[i].1 = dp[i - 1].0 * ((1 << count) - 1);
|
||||||
|
} else {
|
||||||
|
dp[i].1 = (dp[i - 1].0 + dp[i - 1].1) * ((1 << count) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result *= dp[n - 1].0 + dp[n - 1].1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2597() {
|
||||||
|
assert_eq!(4, Solution::beautiful_subsets(vec![2, 4, 6], 2));
|
||||||
|
assert_eq!(1, Solution::beautiful_subsets(vec![1], 1));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* [2610] Convert an Array Into a 2D Array With Conditions
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn find_matrix(nums: Vec<i32>) -> Vec<Vec<i32>> {
|
||||||
|
let mut result = vec![];
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
|
for i in nums {
|
||||||
|
let entry = map.entry(i).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while !map.is_empty() {
|
||||||
|
let mut row = Vec::with_capacity(map.len());
|
||||||
|
for (k, v) in map.iter_mut() {
|
||||||
|
row.push(*k);
|
||||||
|
*v -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
map.retain(|_, &mut x| x != 0);
|
||||||
|
result.push(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2610() {
|
||||||
|
assert_inner_array_unorder_equal!(
|
||||||
|
vec![vec![1, 3, 4, 2], vec![1, 3], vec![1]],
|
||||||
|
Solution::find_matrix(vec![1, 3, 4, 1, 2, 3, 1]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
89
src/problem/p2612_minimum_reverse_operations.rs
Normal file
89
src/problem/p2612_minimum_reverse_operations.rs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/**
|
||||||
|
* [2612] Minimum Reverse Operations
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::{BTreeSet, HashSet, VecDeque};
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn min_reverse_operations(n: i32, p: i32, banned: Vec<i32>, k: i32) -> Vec<i32> {
|
||||||
|
let (n, p) = (n as usize, p as usize);
|
||||||
|
let mut ban_pos: HashSet<usize> =
|
||||||
|
HashSet::from_iter(banned.into_iter().map(|x| x as usize));
|
||||||
|
// 奇数下标和偶数下标是分别连续的
|
||||||
|
// 使用两个二叉树维护
|
||||||
|
let mut odd_pos = BTreeSet::new();
|
||||||
|
let mut even_pos = BTreeSet::new();
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
if i != p && !ban_pos.contains(&i) {
|
||||||
|
if i % 2 == 0 {
|
||||||
|
even_pos.insert(i);
|
||||||
|
} else {
|
||||||
|
odd_pos.insert(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = vec![-1; n];
|
||||||
|
let mut queue = VecDeque::new();
|
||||||
|
queue.push_back(p);
|
||||||
|
result[p] = 0;
|
||||||
|
|
||||||
|
while let Some(front) = queue.pop_front() {
|
||||||
|
// 为了防止usize溢出的诡异类型转换
|
||||||
|
let min_pos = (front as i32 - k + 1).max(k - front as i32 - 1) as usize;
|
||||||
|
let max_pos = (front as i32 + k - 1).min(n as i32 * 2 - k - front as i32 - 1) as usize;
|
||||||
|
|
||||||
|
let mut iter = if max_pos % 2 == 0 {
|
||||||
|
even_pos.range(min_pos..)
|
||||||
|
} else {
|
||||||
|
odd_pos.range(min_pos..)
|
||||||
|
};
|
||||||
|
|
||||||
|
while let Some(&value) = iter.next() {
|
||||||
|
if value > max_pos {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[value] = result[front] + 1;
|
||||||
|
queue.push_back(value);
|
||||||
|
|
||||||
|
iter = if min_pos % 2 == 0 {
|
||||||
|
even_pos.remove(&value);
|
||||||
|
even_pos.range(value + 1..)
|
||||||
|
} else {
|
||||||
|
odd_pos.remove(&value);
|
||||||
|
odd_pos.range(value + 1..)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2612() {
|
||||||
|
assert_eq!(
|
||||||
|
vec![0, -1, -1, 1],
|
||||||
|
Solution::min_reverse_operations(4, 0, vec![1, 2], 4)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
vec![0, -1, -1, -1, -1],
|
||||||
|
Solution::min_reverse_operations(5, 0, vec![2, 4], 3)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
vec![-1, -1, 0, -1],
|
||||||
|
Solution::min_reverse_operations(4, 2, vec![0, 1, 3], 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
52
src/problem/p2614_prime_in_diagonal.rs
Normal file
52
src/problem/p2614_prime_in_diagonal.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* [2614] Prime In Diagonal
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn diagonal_prime(nums: Vec<Vec<i32>>) -> i32 {
|
||||||
|
let n = nums.len();
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
if Self::is_prime(nums[i][i]) {
|
||||||
|
result = result.max(nums[i][i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if Self::is_prime(nums[i][n - i - 1]) {
|
||||||
|
result = result.max(nums[i][n - i - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_prime(num: i32) -> bool {
|
||||||
|
if num == 1 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
!(2..=num.isqrt()).any(|x| num % x == 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2614() {
|
||||||
|
assert_eq!(
|
||||||
|
11,
|
||||||
|
Solution::diagonal_prime(vec![vec![1, 2, 3], vec![5, 6, 7], vec![9, 10, 11]])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
17,
|
||||||
|
Solution::diagonal_prime(vec![vec![1, 2, 3], vec![5, 17, 7], vec![9, 10, 11]])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
48
src/problem/p2643_row_with_maximum_ones.rs
Normal file
48
src/problem/p2643_row_with_maximum_ones.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* [2643] Row With Maximum Ones
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn row_and_maximum_ones(mat: Vec<Vec<i32>>) -> Vec<i32> {
|
||||||
|
let r = mat.iter().enumerate().rev().fold(
|
||||||
|
(mat.len() - 1, 0),
|
||||||
|
|(r_line, r_count), (line, row)| {
|
||||||
|
let c = row.iter().filter(|x| **x == 1).count();
|
||||||
|
|
||||||
|
if c >= r_count {
|
||||||
|
(line, c)
|
||||||
|
} else {
|
||||||
|
(r_line, r_count)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
vec![r.0 as i32, r.1 as i32]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2643() {
|
||||||
|
assert_eq!(
|
||||||
|
vec![0, 1],
|
||||||
|
Solution::row_and_maximum_ones(vec![vec![0, 1], vec![1, 0]])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
vec![1, 2],
|
||||||
|
Solution::row_and_maximum_ones(vec![vec![0, 0, 0], vec![0, 1, 1]])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
vec![1, 2],
|
||||||
|
Solution::row_and_maximum_ones(vec![vec![0, 0], vec![1, 1], vec![0, 0]])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
46
src/problem/p2680_maximum_or.rs
Normal file
46
src/problem/p2680_maximum_or.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* [2680] Maximum OR
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn maximum_or(nums: Vec<i32>, k: i32) -> i64 {
|
||||||
|
let n = nums.len();
|
||||||
|
let k = k as i64;
|
||||||
|
let mut prefix = vec![0; n];
|
||||||
|
let mut suffix = vec![0; n];
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
if i == 0 {
|
||||||
|
prefix[i] = 0;
|
||||||
|
suffix[n - i - 1] = 0;
|
||||||
|
} else {
|
||||||
|
prefix[i] = prefix[i - 1] | nums[i - 1] as i64;
|
||||||
|
suffix[n - i - 1] = suffix[n - i] | nums[n - i] as i64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
for (i, &v) in nums.iter().enumerate() {
|
||||||
|
result = result.max(prefix[i] | ((v as i64) << k) | suffix[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2680() {
|
||||||
|
assert_eq!(30, Solution::maximum_or(vec![12, 9], 1));
|
||||||
|
assert_eq!(35, Solution::maximum_or(vec![8, 1, 2], 2));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/**
|
||||||
|
* [2711] Difference of Number of Distinct Values on Diagonals
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn difference_of_distinct_values(grid: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
|
||||||
|
let m = grid.len();
|
||||||
|
let n = grid[0].len();
|
||||||
|
let mut result = vec![vec![0; n]; m];
|
||||||
|
|
||||||
|
Self::iterate_diagonal(&grid, &mut result, (0..m).rev().map(|i| (i, 0)));
|
||||||
|
Self::iterate_diagonal(&grid, &mut result, (0..n).rev().map(|i| (0, i)));
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iterate_diagonal<T>(grid: &Vec<Vec<i32>>, result: &mut Vec<Vec<i32>>, iter: T)
|
||||||
|
where
|
||||||
|
T: Iterator<Item = (usize, usize)>,
|
||||||
|
{
|
||||||
|
let m = grid.len();
|
||||||
|
let n = grid[0].len();
|
||||||
|
let max_length = m.min(n);
|
||||||
|
|
||||||
|
let mut length = 1;
|
||||||
|
for (i, j) in iter {
|
||||||
|
let mut left_set = HashSet::with_capacity(length);
|
||||||
|
// 右下对角线因为涉及到添加和删除
|
||||||
|
// 使用哈希表存储对应数字的出现次数
|
||||||
|
let mut right_set = HashMap::with_capacity(length);
|
||||||
|
|
||||||
|
// 首先遍历右下
|
||||||
|
let (mut x, mut y) = (i + 1, j + 1);
|
||||||
|
|
||||||
|
for _ in 1..length {
|
||||||
|
let entry = right_set.entry(grid[x][y]).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
|
||||||
|
x += 1;
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 然后开始遍历
|
||||||
|
let (mut x, mut y) = (i, j);
|
||||||
|
|
||||||
|
for k in 0..length {
|
||||||
|
// 删除右下对角线
|
||||||
|
if k != 0 {
|
||||||
|
let entry = right_set.get_mut(&grid[x][y]).unwrap();
|
||||||
|
*entry -= 1;
|
||||||
|
if *entry == 0 {
|
||||||
|
right_set.remove(&grid[x][y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result[x][y] = left_set.len().abs_diff(right_set.len()) as i32;
|
||||||
|
|
||||||
|
// 插入左上对角线
|
||||||
|
left_set.insert(grid[x][y]);
|
||||||
|
x += 1;
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
length = max_length.min(length + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2711() {
|
||||||
|
assert_eq!(
|
||||||
|
vec![vec![1, 1, 0], vec![1, 0, 1], vec![0, 1, 1]],
|
||||||
|
Solution::difference_of_distinct_values(vec![
|
||||||
|
vec![1, 2, 3],
|
||||||
|
vec![3, 1, 5],
|
||||||
|
vec![3, 2, 1]
|
||||||
|
])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
vec![vec![0]],
|
||||||
|
Solution::difference_of_distinct_values(vec![vec![1]])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* [2712] Minimum Cost to Make All Characters Equal
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn minimum_cost(s: String) -> i64 {
|
||||||
|
let mut result = 0;
|
||||||
|
let s: Vec<u8> = s.bytes().collect();
|
||||||
|
|
||||||
|
for i in 1..s.len() {
|
||||||
|
if s[i] != s[i - 1] {
|
||||||
|
result += i.min(s.len() - i) as i64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2712() {
|
||||||
|
assert_eq!(2, Solution::minimum_cost("0011".to_owned()));
|
||||||
|
assert_eq!(9, Solution::minimum_cost("010101".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
30
src/problem/p2716_minimize_string_length.rs
Normal file
30
src/problem/p2716_minimize_string_length.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* [2716] Minimize String Length
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn minimized_string_length(s: String) -> i32 {
|
||||||
|
let set: HashSet<u8> = HashSet::from_iter(s.bytes());
|
||||||
|
|
||||||
|
set.len() as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2716() {
|
||||||
|
assert_eq!(3, Solution::minimized_string_length("aaabc".to_owned()));
|
||||||
|
assert_eq!(3, Solution::minimized_string_length("cbbd".to_owned()));
|
||||||
|
assert_eq!(2, Solution::minimized_string_length("dddaaa".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* [2829] Determine the Minimum Sum of a k-avoiding Array
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn minimum_sum(n: i32, k: i32) -> i32 {
|
||||||
|
let mut avoid_set = HashSet::new();
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
let mut num = 1;
|
||||||
|
|
||||||
|
for _ in 0..n {
|
||||||
|
while avoid_set.contains(&num) {
|
||||||
|
num += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result += num;
|
||||||
|
if k - num > 0 {
|
||||||
|
avoid_set.insert(k - num);
|
||||||
|
}
|
||||||
|
num += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2829() {
|
||||||
|
assert_eq!(18, Solution::minimum_sum(5, 4));
|
||||||
|
assert_eq!(3, Solution::minimum_sum(2, 6));
|
||||||
|
}
|
||||||
|
}
|
42
src/problem/p2843_count_symmetric_integers.rs
Normal file
42
src/problem/p2843_count_symmetric_integers.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
* [2843] Count Symmetric Integers
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_symmetric_integers(low: i32, high: i32) -> i32 {
|
||||||
|
// 10 -> 99 1000 -> 9999
|
||||||
|
(low..=high)
|
||||||
|
.filter_map(|i| {
|
||||||
|
if i >= 10 && i <= 99 {
|
||||||
|
if i / 10 == i % 10 {
|
||||||
|
return Some(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if i >= 1000 && i <= 9999 {
|
||||||
|
if i / 1000 + (i / 100) % 10 == (i / 10) % 10 + i % 10 {
|
||||||
|
return Some(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.count() as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2843() {
|
||||||
|
assert_eq!(9, Solution::count_symmetric_integers(1, 99));
|
||||||
|
assert_eq!(4, Solution::count_symmetric_integers(1200, 1230));
|
||||||
|
}
|
||||||
|
}
|
53
src/problem/p2845_count_of_interesting_subarrays.rs
Normal file
53
src/problem/p2845_count_of_interesting_subarrays.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* [2845] Count of Interesting Subarrays
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_interesting_subarrays(nums: Vec<i32>, modulo: i32, k: i32) -> i64 {
|
||||||
|
let n = nums.len();
|
||||||
|
let mut count = vec![0; n + 1];
|
||||||
|
for (i, &v) in nums.iter().enumerate() {
|
||||||
|
count[i + 1] = count[i] + if v % modulo == k { 1 } else { 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
// 类似于两数之和
|
||||||
|
for i in 0..=n {
|
||||||
|
let target = (count[i] + modulo - k) % modulo;
|
||||||
|
|
||||||
|
if let Some(&v) = map.get(&target) {
|
||||||
|
result += v;
|
||||||
|
}
|
||||||
|
|
||||||
|
let entry = map.entry(count[i] % modulo).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2845() {
|
||||||
|
assert_eq!(
|
||||||
|
3,
|
||||||
|
Solution::count_interesting_subarrays(vec![3, 2, 4], 2, 1)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
2,
|
||||||
|
Solution::count_interesting_subarrays(vec![3, 1, 9, 6], 3, 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
39
src/problem/p2873_maximum_value_of_an_ordered_triplet_i.rs
Normal file
39
src/problem/p2873_maximum_value_of_an_ordered_triplet_i.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* [2873] Maximum Value of an Ordered Triplet I
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn maximum_triplet_value(nums: Vec<i32>) -> i64 {
|
||||||
|
let nums: Vec<i64> = nums.into_iter().map(|x| x as i64).collect();
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
let n = nums.len();
|
||||||
|
|
||||||
|
for i in 0..n {
|
||||||
|
for j in i + 1..n {
|
||||||
|
for k in j + 1..n {
|
||||||
|
result = result.max((nums[i] - nums[j]) * nums[k])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2873() {
|
||||||
|
assert_eq!(77, Solution::maximum_triplet_value(vec![12, 6, 1, 2, 7]));
|
||||||
|
assert_eq!(133, Solution::maximum_triplet_value(vec![1, 10, 3, 4, 19]));
|
||||||
|
assert_eq!(0, Solution::maximum_triplet_value(vec![1, 2, 3]));
|
||||||
|
}
|
||||||
|
}
|
47
src/problem/p2874_maximum_value_of_an_ordered_triplet_ii.rs
Normal file
47
src/problem/p2874_maximum_value_of_an_ordered_triplet_ii.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* [2874] Maximum Value of an Ordered Triplet II
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn maximum_triplet_value(nums: Vec<i32>) -> i64 {
|
||||||
|
let nums: Vec<i64> = nums.into_iter().map(|x| x as i64).collect();
|
||||||
|
let n = nums.len();
|
||||||
|
// max num from nums[0] to nums[i]
|
||||||
|
let mut prefix = vec![0; n];
|
||||||
|
// max num from nums[i] to nums[n - 1]
|
||||||
|
let mut suffix = vec![0; n];
|
||||||
|
|
||||||
|
prefix[0] = nums[0];
|
||||||
|
suffix[n - 1] = nums[n - 1];
|
||||||
|
|
||||||
|
for i in 1..n {
|
||||||
|
prefix[i] = nums[i].max(prefix[i - 1]);
|
||||||
|
suffix[n - i - 1] = nums[n - i - 1].max(suffix[n - i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
for j in 1..n - 1 {
|
||||||
|
result = result.max((prefix[j - 1] - nums[j]) * suffix[j + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2874() {
|
||||||
|
assert_eq!(77, Solution::maximum_triplet_value(vec![12, 6, 1, 2, 7]));
|
||||||
|
assert_eq!(133, Solution::maximum_triplet_value(vec![1, 10, 3, 4, 19]));
|
||||||
|
assert_eq!(0, Solution::maximum_triplet_value(vec![1, 2, 3]));
|
||||||
|
}
|
||||||
|
}
|
111
src/problem/p2999_count_the_number_of_powerful_integers.rs
Normal file
111
src/problem/p2999_count_the_number_of_powerful_integers.rs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/**
|
||||||
|
* [2999] Count the Number of Powerful Integers
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
struct Searcher {
|
||||||
|
low: Vec<u8>,
|
||||||
|
high: Vec<u8>,
|
||||||
|
suffix: Vec<u8>,
|
||||||
|
memory: Vec<i64>,
|
||||||
|
limit: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Searcher {
|
||||||
|
fn new(start: i64, finish: i64, limit: i32, s: String) -> Self {
|
||||||
|
let mut low: Vec<u8> = start.to_string().bytes().map(|x| x - b'0').collect();
|
||||||
|
let high: Vec<u8> = finish.to_string().bytes().map(|x| x - b'0').collect();
|
||||||
|
|
||||||
|
// 对齐low和high的数位
|
||||||
|
for _ in 0..high.len() - low.len() {
|
||||||
|
low.insert(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let suffix = s.bytes().map(|x| x - b'0').collect();
|
||||||
|
let n = high.len();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
low,
|
||||||
|
high,
|
||||||
|
suffix,
|
||||||
|
memory: vec![-1; n],
|
||||||
|
limit: limit as u8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search(&mut self, i: usize, limit_low: bool, limit_high: bool) -> i64 {
|
||||||
|
if i == self.low.len() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !limit_low && !limit_high && self.memory[i] != -1 {
|
||||||
|
return self.memory[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
let low = if limit_low { self.low[i] } else { 0 };
|
||||||
|
|
||||||
|
let high = if limit_high { self.high[i] } else { 9 };
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
let prefix_len = self.low.len() - self.suffix.len();
|
||||||
|
if i < prefix_len {
|
||||||
|
for digit in low..=high.min(self.limit) {
|
||||||
|
result += self.search(
|
||||||
|
i + 1,
|
||||||
|
limit_low && digit == low,
|
||||||
|
limit_high && digit == high,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let digit = self.suffix[i - prefix_len];
|
||||||
|
if digit >= low && digit <= high.min(self.limit) {
|
||||||
|
result = self.search(
|
||||||
|
i + 1,
|
||||||
|
limit_low && digit == low,
|
||||||
|
limit_high && digit == high,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !limit_low && !limit_high {
|
||||||
|
self.memory[i] = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn number_of_powerful_int(start: i64, finish: i64, limit: i32, s: String) -> i64 {
|
||||||
|
let mut searcher = Searcher::new(start, finish, limit, s);
|
||||||
|
|
||||||
|
searcher.search(0, true, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2999() {
|
||||||
|
assert_eq!(
|
||||||
|
5,
|
||||||
|
Solution::number_of_powerful_int(1, 6000, 4, "123".to_owned())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
2,
|
||||||
|
Solution::number_of_powerful_int(15, 215, 6, "10".to_owned())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
0,
|
||||||
|
Solution::number_of_powerful_int(1000, 2000, 4, "3000".to_owned())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
28
src/problem/p3110_score_of_a_string.rs
Normal file
28
src/problem/p3110_score_of_a_string.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* [3110] Score of a String
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn score_of_string(s: String) -> i32 {
|
||||||
|
s.bytes()
|
||||||
|
.zip(s.bytes().skip(1))
|
||||||
|
.map(|(first, second)| first.abs_diff(second) as i32)
|
||||||
|
.sum::<i32>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_3110() {
|
||||||
|
assert_eq!(13, Solution::score_of_string("hello".to_owned()));
|
||||||
|
assert_eq!(50, Solution::score_of_string("zaz".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
81
src/problem/p3272_find_the_count_of_good_integers.rs
Normal file
81
src/problem/p3272_find_the_count_of_good_integers.rs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
* [3272] Find the Count of Good Integers
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_good_integers(n: i32, k: i32) -> i64 {
|
||||||
|
let n = n as usize;
|
||||||
|
let k = k as i64;
|
||||||
|
let base_value = 10i64.pow((n as u32 - 1) / 2);
|
||||||
|
let length = (n + 1) / 2;
|
||||||
|
let mut dict = HashSet::new();
|
||||||
|
|
||||||
|
// 枚举n个数位的回文数
|
||||||
|
for mut i in base_value..base_value * 10 {
|
||||||
|
let mut s = Vec::with_capacity(length);
|
||||||
|
|
||||||
|
while i != 0 {
|
||||||
|
s.push(i % 10);
|
||||||
|
i = i / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这里拼接回文字符串有点困难
|
||||||
|
// 因为上面存数字字符存的是倒序
|
||||||
|
// 即 123 -> 3 2 1
|
||||||
|
// 所以 12321 -> 1 2 3 2 1
|
||||||
|
let mut real_str: Vec<i64> = s
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.chain(s.iter().skip(n & 1))
|
||||||
|
.map(|x| *x)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let number = real_str.iter().fold(0, |v, i| v * 10 + *i);
|
||||||
|
if number % k == 0 {
|
||||||
|
real_str.sort_unstable();
|
||||||
|
dict.insert(real_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut factorial = Vec::with_capacity(n + 1);
|
||||||
|
factorial.push(1);
|
||||||
|
for i in 1..=n {
|
||||||
|
factorial.push(factorial[i - 1] * i as i64);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
for str in dict.into_iter() {
|
||||||
|
let mut counts = [0; 10];
|
||||||
|
for i in str {
|
||||||
|
counts[i as usize] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut total = (n - counts[0]) as i64 * factorial[n - 1];
|
||||||
|
for x in counts {
|
||||||
|
total /= factorial[x]
|
||||||
|
}
|
||||||
|
result += total;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_3272() {
|
||||||
|
assert_eq!(27, Solution::count_good_integers(3, 5));
|
||||||
|
assert_eq!(2, Solution::count_good_integers(1, 4));
|
||||||
|
assert_eq!(2468, Solution::count_good_integers(5, 6));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* [3305] Count of Substrings Containing Every Vowel and K Consonants I
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_of_substrings(word: String, k: i32) -> i32 {
|
||||||
|
let word: Vec<char> = word.chars().collect();
|
||||||
|
let vowel_set = HashSet::from(['a', 'e', 'i', 'o', 'u']);
|
||||||
|
|
||||||
|
let count = |m| -> i32 {
|
||||||
|
let mut consonants = 0;
|
||||||
|
let mut result = 0;
|
||||||
|
let mut occurence = HashMap::new();
|
||||||
|
|
||||||
|
let mut right = 0;
|
||||||
|
for left in 0..word.len() {
|
||||||
|
while right < word.len() && (consonants < m || occurence.len() < vowel_set.len()) {
|
||||||
|
if vowel_set.contains(&word[right]) {
|
||||||
|
let entry = occurence.entry(word[right]).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
} else {
|
||||||
|
consonants += 1;
|
||||||
|
}
|
||||||
|
right += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if consonants >= m && occurence.len() == vowel_set.len() {
|
||||||
|
result += (word.len() - right + 1) as i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
if vowel_set.contains(&word[left]) {
|
||||||
|
let v = occurence.get_mut(&word[left]).unwrap();
|
||||||
|
*v -= 1;
|
||||||
|
if *v == 0 {
|
||||||
|
occurence.remove(&word[left]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
consonants -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
};
|
||||||
|
|
||||||
|
count(k) - count(k + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_3305() {
|
||||||
|
assert_eq!(3, Solution::count_of_substrings("auieoui".to_owned(), 0));
|
||||||
|
assert_eq!(2, Solution::count_of_substrings("ieiaoud".to_owned(), 0));
|
||||||
|
assert_eq!(3, Solution::count_of_substrings("iqeaouqi".to_owned(), 2));
|
||||||
|
assert_eq!(
|
||||||
|
3,
|
||||||
|
Solution::count_of_substrings("ieaouqqieaouqq".to_owned(), 1)
|
||||||
|
);
|
||||||
|
assert_eq!(0, Solution::count_of_substrings("aeioqq".to_owned(), 1));
|
||||||
|
assert_eq!(1, Solution::count_of_substrings("aeiou".to_owned(), 0));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* [3306] Count of Substrings Containing Every Vowel and K Consonants II
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn count_of_substrings(word: String, k: i32) -> i64 {
|
||||||
|
let word: Vec<char> = word.chars().collect();
|
||||||
|
let vowel_set = HashSet::from(['a', 'e', 'i', 'o', 'u']);
|
||||||
|
|
||||||
|
let count = |m| -> i64 {
|
||||||
|
let mut consonants = 0;
|
||||||
|
let mut result = 0;
|
||||||
|
let mut occurence = HashMap::new();
|
||||||
|
|
||||||
|
let mut right = 0;
|
||||||
|
for left in 0..word.len() {
|
||||||
|
while right < word.len() && (consonants < m || occurence.len() < vowel_set.len()) {
|
||||||
|
if vowel_set.contains(&word[right]) {
|
||||||
|
let entry = occurence.entry(word[right]).or_insert(0i64);
|
||||||
|
*entry += 1;
|
||||||
|
} else {
|
||||||
|
consonants += 1;
|
||||||
|
}
|
||||||
|
right += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if consonants >= m && occurence.len() == vowel_set.len() {
|
||||||
|
result += (word.len() - right + 1) as i64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if vowel_set.contains(&word[left]) {
|
||||||
|
let v = occurence.get_mut(&word[left]).unwrap();
|
||||||
|
*v -= 1;
|
||||||
|
if *v == 0 {
|
||||||
|
occurence.remove(&word[left]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
consonants -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
};
|
||||||
|
|
||||||
|
count(k) - count(k + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_3306() {
|
||||||
|
assert_eq!(0, Solution::count_of_substrings("aeioqq".to_owned(), 1));
|
||||||
|
}
|
||||||
|
}
|
27
src/problem/p3340_check_balanced_string.rs
Normal file
27
src/problem/p3340_check_balanced_string.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* [3340] Check Balanced String
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn is_balanced(num: String) -> bool {
|
||||||
|
let num: Vec<i32> = num.bytes().map(|x| (x - b'0') as i32).collect();
|
||||||
|
|
||||||
|
num.iter().step_by(2).sum::<i32>() == num.iter().skip(1).step_by(2).sum::<i32>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_3340() {
|
||||||
|
assert!(!Solution::is_balanced("1234".to_owned()));
|
||||||
|
assert!(Solution::is_balanced("24123".to_owned()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* [3375] Minimum Operations to Make Array Values Equal to K
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn min_operations(nums: Vec<i32>, k: i32) -> i32 {
|
||||||
|
let set: HashSet<i32> = nums.into_iter().collect();
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
for &i in set.iter() {
|
||||||
|
if i < k {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if i > k {
|
||||||
|
result += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_3375() {
|
||||||
|
assert_eq!(2, Solution::min_operations(vec![5, 2, 5, 4, 5], 2));
|
||||||
|
assert_eq!(-1, Solution::min_operations(vec![2, 1, 2], 2));
|
||||||
|
assert_eq!(4, Solution::min_operations(vec![9, 7, 5, 3], 1));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* [3396] Minimum Number of Operations to Make Elements in Array Distinct
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn minimum_operations(nums: Vec<i32>) -> i32 {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
|
for &i in nums.iter() {
|
||||||
|
let mut entry = map.entry(i).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
let mut pos = 0;
|
||||||
|
|
||||||
|
while pos < nums.len() {
|
||||||
|
if map.values().all(|i| *i == 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for p in pos..(pos + 3).min(nums.len()) {
|
||||||
|
pos = p;
|
||||||
|
let value = map.get_mut(&nums[pos]).unwrap();
|
||||||
|
*value -= 1;
|
||||||
|
}
|
||||||
|
pos += 1;
|
||||||
|
|
||||||
|
result += 1;
|
||||||
|
map.retain(|_, v| *v != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_3396() {
|
||||||
|
assert_eq!(2, Solution::minimum_operations(vec![5, 7, 11, 12, 12]));
|
||||||
|
assert_eq!(
|
||||||
|
2,
|
||||||
|
Solution::minimum_operations(vec![1, 2, 3, 4, 2, 3, 3, 5, 7])
|
||||||
|
);
|
||||||
|
assert_eq!(2, Solution::minimum_operations(vec![4, 5, 6, 4, 4]));
|
||||||
|
assert_eq!(0, Solution::minimum_operations(vec![6, 7, 8, 9]));
|
||||||
|
}
|
||||||
|
}
|
72
src/problem/p368_largest_divisible_subset.rs
Normal file
72
src/problem/p368_largest_divisible_subset.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* [368] Largest Divisible Subset
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn largest_divisible_subset(mut nums: Vec<i32>) -> Vec<i32> {
|
||||||
|
nums.sort_unstable();
|
||||||
|
let n = nums.len();
|
||||||
|
|
||||||
|
let mut dp = vec![1; n];
|
||||||
|
let mut max_size = 1;
|
||||||
|
let mut max_value = nums[0];
|
||||||
|
|
||||||
|
for i in 1..n {
|
||||||
|
for j in 0..i {
|
||||||
|
if nums[i] % nums[j] == 0 {
|
||||||
|
dp[i] = dp[i].max(dp[j] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dp[i] > max_size {
|
||||||
|
max_size = dp[i];
|
||||||
|
max_value = nums[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得求得的最大子集
|
||||||
|
let mut result = vec![];
|
||||||
|
|
||||||
|
if max_size == 1 {
|
||||||
|
result.push(nums[0]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in (0..n).rev() {
|
||||||
|
if dp[i] == max_size && max_value % nums[i] == 0 {
|
||||||
|
result.push(nums[i]);
|
||||||
|
max_value = nums[i];
|
||||||
|
max_size -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if max_size <= 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_368() {
|
||||||
|
assert_array_unorder_equal!(vec![1], Solution::largest_divisible_subset(vec![1]));
|
||||||
|
assert_array_unorder_equal!(
|
||||||
|
vec![1, 2],
|
||||||
|
Solution::largest_divisible_subset(vec![1, 2, 3])
|
||||||
|
);
|
||||||
|
assert_array_unorder_equal!(
|
||||||
|
vec![1, 2, 4, 8],
|
||||||
|
Solution::largest_divisible_subset(vec![1, 2, 4, 8])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
58
src/problem/p416_partition_equal_subset_sum.rs
Normal file
58
src/problem/p416_partition_equal_subset_sum.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* [416] Partition Equal Subset Sum
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn can_partition(nums: Vec<i32>) -> bool {
|
||||||
|
let n = nums.len();
|
||||||
|
if n < 2 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let nums: Vec<usize> = nums.into_iter().map(|x| x as usize).collect();
|
||||||
|
let sum: usize = nums.iter().sum();
|
||||||
|
|
||||||
|
if sum % 2 != 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let middle = sum / 2;
|
||||||
|
let mut dp = vec![vec![false; middle + 1]; n];
|
||||||
|
|
||||||
|
// 初始化dp
|
||||||
|
for i in 0..n {
|
||||||
|
dp[i][0] = true;
|
||||||
|
}
|
||||||
|
if nums[0] <= middle {
|
||||||
|
dp[0][nums[0]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 1..n {
|
||||||
|
for j in 1..=middle {
|
||||||
|
if j < nums[i] {
|
||||||
|
dp[i][j] = dp[i - 1][j];
|
||||||
|
} else {
|
||||||
|
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dp[n - 1][middle]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_416() {
|
||||||
|
assert!(Solution::can_partition(vec![1, 5, 11, 5]));
|
||||||
|
assert!(!Solution::can_partition(vec![1, 2, 3, 5]));
|
||||||
|
}
|
||||||
|
}
|
43
src/problem/p624_maximum_distance_in_arrays.rs
Normal file
43
src/problem/p624_maximum_distance_in_arrays.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
use std::thread::available_parallelism;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [624] Maximum Distance in Arrays
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn max_distance(arrays: Vec<Vec<i32>>) -> i32 {
|
||||||
|
let mut result = 0;
|
||||||
|
// -10e4 <= array[i][j] <= 10e4
|
||||||
|
let (mut min, mut max) = (10_000 + 1, -10_000 - 1);
|
||||||
|
|
||||||
|
for array in arrays {
|
||||||
|
result = result
|
||||||
|
.max(*array.last().unwrap() - min)
|
||||||
|
.max(max - *array.first().unwrap());
|
||||||
|
|
||||||
|
min = min.min(*array.first().unwrap());
|
||||||
|
max = max.max(*array.last().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_624() {
|
||||||
|
assert_eq!(
|
||||||
|
4,
|
||||||
|
Solution::max_distance(vec![vec![1, 2, 3], vec![4, 5], vec![1, 2, 3]])
|
||||||
|
);
|
||||||
|
assert_eq!(0, Solution::max_distance(vec![vec![1], vec![1]]));
|
||||||
|
}
|
||||||
|
}
|
46
src/problem/p781_rabbits_in_forest.rs
Normal file
46
src/problem/p781_rabbits_in_forest.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* [781] Rabbits in Forest
|
||||||
|
*/
|
||||||
|
pub struct Solution {}
|
||||||
|
|
||||||
|
// submission codes start here
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
impl Solution {
|
||||||
|
pub fn num_rabbits(answers: Vec<i32>) -> i32 {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
|
for i in answers.into_iter() {
|
||||||
|
let entry = map.entry(i).or_insert(0);
|
||||||
|
*entry += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = 0;
|
||||||
|
|
||||||
|
for (k, mut v) in map.into_iter() {
|
||||||
|
// 同种颜色兔子最多有k + 1个
|
||||||
|
let max_count = k + 1;
|
||||||
|
|
||||||
|
while v > 0 {
|
||||||
|
result += max_count;
|
||||||
|
v -= max_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// submission codes end
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_781() {
|
||||||
|
assert_eq!(5, Solution::num_rabbits(vec![1, 0, 1, 0, 0]));
|
||||||
|
assert_eq!(5, Solution::num_rabbits(vec![1, 1, 2]));
|
||||||
|
assert_eq!(11, Solution::num_rabbits(vec![10, 10, 10]))
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,3 +6,5 @@ pub mod vec_string;
|
||||||
pub mod tree;
|
pub mod tree;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod point;
|
pub mod point;
|
||||||
|
#[macro_use]
|
||||||
|
pub mod vec_equal;
|
||||||
|
|
51
src/util/vec_equal.rs
Normal file
51
src/util/vec_equal.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::hash::Hash;
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
pub fn assert_array_unorder_equal<T>(a: &Vec<T>, b: &Vec<T>)
|
||||||
|
where
|
||||||
|
T: Eq,
|
||||||
|
T: Hash,
|
||||||
|
{
|
||||||
|
assert_eq!(a.len(), b.len());
|
||||||
|
|
||||||
|
let set: HashSet<&T> = HashSet::from_iter(a.into_iter());
|
||||||
|
|
||||||
|
for i in b.iter() {
|
||||||
|
assert!(set.contains(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! assert_array_unorder_equal {
|
||||||
|
($left:expr, $right:expr $(,)?) => {
|
||||||
|
match (&$left, &$right) {
|
||||||
|
(left_value, right_value) => {
|
||||||
|
$crate::util::vec_equal::assert_array_unorder_equal(left_value, right_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assert_inner_array_unorder_equal<T>(a: &Vec<Vec<T>>, b: &Vec<Vec<T>>)
|
||||||
|
where
|
||||||
|
T: Eq,
|
||||||
|
T: Hash,
|
||||||
|
{
|
||||||
|
assert_eq!(a.len(), b.len());
|
||||||
|
|
||||||
|
for (i, j) in a.iter().zip(b.iter()) {
|
||||||
|
assert_array_unorder_equal(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! assert_inner_array_unorder_equal {
|
||||||
|
($left:expr, $right:expr $(,)?) => {
|
||||||
|
match (&$left, &$right) {
|
||||||
|
(left_value, right_value) => {
|
||||||
|
$crate::util::vec_equal::assert_inner_array_unorder_equal(left_value, right_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user