add ex
This commit is contained in:
parent
7c2272c86c
commit
1b43648d4c
91
src/arrays/2016MaxDiffBetweenIncreasingEl.rs
Normal file
91
src/arrays/2016MaxDiffBetweenIncreasingEl.rs
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
2016. Maximum Difference Between Increasing Elements
|
||||
Solved
|
||||
Easy
|
||||
Topics
|
||||
premium lock iconCompanies
|
||||
Hint
|
||||
|
||||
Given a 0-indexed integer array nums of size n, find the maximum difference between nums[i] and nums[j] (i.e., nums[j] - nums[i]), such that 0 <= i < j < n and nums[i] < nums[j].
|
||||
|
||||
Return the maximum difference. If no such i and j exists, return -1.
|
||||
|
||||
|
||||
|
||||
Example 1:
|
||||
|
||||
Input: nums = [7,1,5,4]
|
||||
Output: 4
|
||||
Explanation:
|
||||
The maximum difference occurs with i = 1 and j = 2, nums[j] - nums[i] = 5 - 1 = 4.
|
||||
Note that with i = 1 and j = 0, the difference nums[j] - nums[i] = 7 - 1 = 6, but i > j, so it is not valid.
|
||||
|
||||
Example 2:
|
||||
|
||||
Input: nums = [9,4,3,2]
|
||||
Output: -1
|
||||
Explanation:
|
||||
There is no i and j such that i < j and nums[i] < nums[j].
|
||||
|
||||
Example 3:
|
||||
|
||||
Input: nums = [1,5,2,10]
|
||||
Output: 9
|
||||
Explanation:
|
||||
The maximum difference occurs with i = 0 and j = 3, nums[j] - nums[i] = 10 - 1 = 9.
|
||||
|
||||
|
||||
|
||||
Constraints:
|
||||
|
||||
n == nums.length
|
||||
2 <= n <= 1000
|
||||
1 <= nums[i] <= 109
|
||||
|
||||
|
||||
*/
|
||||
|
||||
pub fn maximum_difference(nums: Vec<i32>) -> i32 {
|
||||
nums.iter()
|
||||
.rev()
|
||||
.scan(i32::MIN, |acc, el| {
|
||||
*acc = (*acc).max(*el);
|
||||
Some(*acc)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.iter()
|
||||
.rev()
|
||||
.skip(1)
|
||||
.zip(nums.iter().scan(i32::MAX, |acc, el| {
|
||||
*acc = (*acc).min(*el);
|
||||
Some(*acc)
|
||||
}))
|
||||
.map(|(max, min)| max - min)
|
||||
.filter(|x| *x > 0)
|
||||
.max()
|
||||
.unwrap_or(-1)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maximum_difference() {
|
||||
assert_eq!(maximum_difference(vec![9, 4, 3, 2]), -1);
|
||||
assert_eq!(maximum_difference(vec![7, 1, 5, 4]), 4);
|
||||
assert_eq!(maximum_difference(vec![1, 5, 2, 10]), 9);
|
||||
assert_eq!(maximum_difference(vec![1, 1, 1]), -1);
|
||||
assert_eq!(maximum_difference(vec![1]), -1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maximum_difference2() {
|
||||
assert_eq!(
|
||||
maximum_difference(vec![
|
||||
999, 997, 980, 976, 948, 940, 938, 928, 924, 917, 907, 907, 881, 878, 864, 862, 859,
|
||||
857, 848, 840, 824, 824, 824, 805, 802, 798, 788, 777, 775, 766, 755, 748, 735, 732,
|
||||
727, 705, 700, 697, 693, 679, 676, 644, 634, 624, 599, 596, 588, 583, 562, 558, 553,
|
||||
539, 537, 536, 509, 491, 485, 483, 454, 449, 438, 425, 403, 368, 345, 327, 287, 285,
|
||||
270, 263, 255, 248, 235, 234, 224, 221, 201, 189, 187, 183, 179, 168, 155, 153, 150,
|
||||
144, 107, 102, 102, 87, 80, 57, 55, 49, 48, 45, 26, 26, 23, 15
|
||||
]),
|
||||
-1
|
||||
);
|
||||
}
|
||||
91
src/arrays/2966DivideArrayIntoArrWithMaxDiff.rs
Normal file
91
src/arrays/2966DivideArrayIntoArrWithMaxDiff.rs
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
2966. Divide Array Into Arrays With Max Difference
|
||||
Solved
|
||||
Medium
|
||||
Topics
|
||||
premium lock iconCompanies
|
||||
Hint
|
||||
|
||||
You are given an integer array nums of size n where n is a multiple of 3 and a positive integer k.
|
||||
|
||||
Divide the array nums into n / 3 arrays of size 3 satisfying the following condition:
|
||||
|
||||
The difference between any two elements in one array is less than or equal to k.
|
||||
|
||||
Return a 2D array containing the arrays. If it is impossible to satisfy the conditions, return an empty array. And if there are multiple answers, return any of them.
|
||||
|
||||
|
||||
|
||||
Example 1:
|
||||
|
||||
Input: nums = [1,3,4,8,7,9,3,5,1], k = 2
|
||||
|
||||
Output: [[1,1,3],[3,4,5],[7,8,9]]
|
||||
|
||||
Explanation:
|
||||
|
||||
The difference between any two elements in each array is less than or equal to 2.
|
||||
|
||||
Example 2:
|
||||
|
||||
Input: nums = [2,4,2,2,5,2], k = 2
|
||||
|
||||
Output: []
|
||||
|
||||
Explanation:
|
||||
|
||||
Different ways to divide nums into 2 arrays of size 3 are:
|
||||
|
||||
[[2,2,2],[2,4,5]] (and its permutations)
|
||||
[[2,2,4],[2,2,5]] (and its permutations)
|
||||
|
||||
Because there are four 2s there will be an array with the elements 2 and 5 no matter how we divide it. since 5 - 2 = 3 > k, the condition is not satisfied and so there is no valid division.
|
||||
|
||||
Example 3:
|
||||
|
||||
Input: nums = [4,2,9,8,2,12,7,12,10,5,8,5,5,7,9,2,5,11], k = 14
|
||||
|
||||
Output: [[2,2,12],[4,8,5],[5,9,7],[7,8,5],[5,9,10],[11,12,2]]
|
||||
|
||||
Explanation:
|
||||
|
||||
The difference between any two elements in each array is less than or equal to 14.
|
||||
|
||||
|
||||
|
||||
Constraints:
|
||||
|
||||
n == nums.length
|
||||
1 <= n <= 105
|
||||
n is a multiple of 3
|
||||
1 <= nums[i] <= 105
|
||||
1 <= k <= 105
|
||||
|
||||
*/
|
||||
|
||||
|
||||
pub fn divide_array(mut nums: Vec<i32>, k: i32) -> Vec<Vec<i32>> {
|
||||
nums.sort_unstable();
|
||||
let res = nums
|
||||
.chunks( 3)
|
||||
.map(|c| c.iter().map(|x| *x).collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>();
|
||||
if res
|
||||
.iter()
|
||||
.any(|x| x.last().unwrap() - x.first().unwrap() > k)
|
||||
{
|
||||
vec![]
|
||||
} else {
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_divide2() {
|
||||
let res = vec![2,4,2,2,5,2];
|
||||
assert_eq!(
|
||||
divide_array(res, 2),
|
||||
Vec::<Vec<i32>>::new()
|
||||
);
|
||||
}
|
||||
869
src/main.rs
869
src/main.rs
@ -7,21 +7,17 @@ use play::{
|
||||
test_two_arms,
|
||||
},
|
||||
};
|
||||
use std::collections::BinaryHeap;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
char,
|
||||
collections::VecDeque,
|
||||
f32::MIN,
|
||||
i32,
|
||||
fmt::Debug,
|
||||
i32, iter,
|
||||
ops::{Add, Mul},
|
||||
rc::Rc,
|
||||
time::Instant,
|
||||
sync::atomic::{AtomicU64, Ordering},
|
||||
time::{Instant, SystemTime},
|
||||
usize, vec,
|
||||
};
|
||||
use std::{cmp::Reverse, ptr};
|
||||
macro_rules! st {
|
||||
($($token:expr),*) => {
|
||||
vec![$($token.to_string()),*]
|
||||
@ -33,796 +29,93 @@ fn main() {
|
||||
// let root = test_01();
|
||||
let root2 = full_tree_level(2, 15);
|
||||
let now = Instant::now();
|
||||
println!(
|
||||
"{:?}",
|
||||
eventual_safe_nodes(vec![vec![1,2],vec![2,3],vec![5],vec![0],vec![5],vec![],vec![]]
|
||||
)
|
||||
);
|
||||
// println!(
|
||||
// "{:?}",
|
||||
//count_subarrays(vec![3, 7, 8, 10, 10, 2, 7, 2, 5, 1], 90)
|
||||
// push_dominoes(".L.R...LR..L..".to_string())
|
||||
// lexical_order(10458)
|
||||
// );
|
||||
println!("Elapsed: {:?}", now.elapsed().as_millis());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum State {
|
||||
Unknown,
|
||||
Seen,
|
||||
UnSafe,
|
||||
Safe
|
||||
}
|
||||
|
||||
pub fn eventual_safe_nodes(graph: Vec<Vec<i32>>) -> Vec<i32> {
|
||||
fn is_node_safe(start: usize, graph: &[Vec<i32>], safe_map: &mut [State]) ->State {
|
||||
match safe_map[start] {
|
||||
State::Safe => return State::Safe,
|
||||
State::UnSafe | State::Seen => return State::UnSafe,
|
||||
_ => {}
|
||||
}
|
||||
safe_map[start] = State::Seen;
|
||||
|
||||
for n in &graph[start] {
|
||||
safe_map[*n as usize] = is_node_safe(*n as usize, graph, safe_map);
|
||||
match safe_map[*n as usize] {
|
||||
State::Safe => continue,
|
||||
State::UnSafe | State::Seen => return State::UnSafe,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
State::Safe
|
||||
}
|
||||
let mut safe_map = vec![State::Unknown; graph.len()];
|
||||
for i in 0..graph.len() {
|
||||
if graph[i].is_empty() {
|
||||
safe_map[i] = State::Safe;
|
||||
}
|
||||
}
|
||||
|
||||
let mut re = Vec::new();
|
||||
for i in 0..graph.len() {
|
||||
match is_node_safe(i, &graph, &mut safe_map) {
|
||||
State::Safe => re.push(i as i32),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
}
|
||||
re
|
||||
}
|
||||
pub fn eventual_safe_nodes1(graph: Vec<Vec<i32>>) -> Vec<i32> {
|
||||
fn is_node_safe(start: usize, graph: &[Vec<i32>], safe_map: &mut [Option<bool>] , seen: &mut [bool]) -> bool {
|
||||
if let Some(x) = safe_map[start] {
|
||||
return x;
|
||||
}
|
||||
|
||||
for n in &graph[start] {
|
||||
if let Some(child_safe) = safe_map[*n as usize] {
|
||||
if !child_safe{
|
||||
return false;
|
||||
}
|
||||
} else if seen[*n as usize] {
|
||||
safe_map[*n as usize] = Some(false);
|
||||
return false;
|
||||
} else {
|
||||
seen[*n as usize] = true;
|
||||
let child_safe = is_node_safe(*n as usize, graph, safe_map, seen);
|
||||
safe_map[*n as usize] = Some(child_safe);
|
||||
if !child_safe {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
let mut safe_map = vec![None; graph.len()];
|
||||
let mut seen = vec![false; graph.len()];
|
||||
for i in 0..graph.len() {
|
||||
if graph[i].is_empty() {
|
||||
safe_map[i] = Some(true);
|
||||
seen[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
let mut re = Vec::new();
|
||||
for i in 0..graph.len() {
|
||||
if is_node_safe(i, &graph, &mut safe_map, &mut seen) {
|
||||
re.push(i as i32);
|
||||
}
|
||||
}
|
||||
re
|
||||
}
|
||||
|
||||
pub fn count_servers(grid: Vec<Vec<i32>>) -> i32 {
|
||||
let num_rows = grid.len();
|
||||
grid.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, r)| {
|
||||
let mut it = r.iter().enumerate().filter(|(_, &x)| x == 1);
|
||||
let first = it.next();
|
||||
if it.next().is_none() {
|
||||
first.map(|(j, _)| (i, j))
|
||||
} else {
|
||||
None
|
||||
pub fn divide_string(s: String, k: i32, fill: char) -> Vec<String> {
|
||||
s.as_bytes()
|
||||
.chunks(k as usize)
|
||||
.map(|c| {
|
||||
let mut chunk: Vec<char> = c.iter().map(|&x| x as char).collect();
|
||||
while chunk.len() < k as usize {
|
||||
chunk.push(fill);
|
||||
}
|
||||
chunk.into_iter().collect()
|
||||
})
|
||||
.filter(|(i, j)| (0..num_rows).any(|k| grid[k][*j] == 1 && k != *i))
|
||||
.count() as i32
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub fn count_servers2(grid: Vec<Vec<i32>>) -> i32 {
|
||||
let mut set = HashSet::new();
|
||||
let mut seen_in_col = vec![usize::MAX; grid[0].len()];
|
||||
for i in 0..grid.len() {
|
||||
let mut seen_in_row = usize::MAX;
|
||||
for j in 0..grid[0].len() {
|
||||
if grid[i][j] == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if seen_in_col[j] != usize::MAX {
|
||||
set.insert((i, j));
|
||||
set.insert((seen_in_col[j], j));
|
||||
} else {
|
||||
seen_in_col[j] = i;
|
||||
}
|
||||
|
||||
if seen_in_row != usize::MAX {
|
||||
set.insert((i, j));
|
||||
set.insert((i, seen_in_row));
|
||||
} else {
|
||||
seen_in_row = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
set.len() as i32
|
||||
}
|
||||
|
||||
pub fn highest_peak(is_water: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
|
||||
let mut queue = VecDeque::new();
|
||||
let n = is_water.len();
|
||||
let m = is_water[0].len();
|
||||
let mut res = vec![vec![i32::MAX; m]; n];
|
||||
for i in 0..is_water.len() {
|
||||
for j in 0..is_water[0].len() {
|
||||
if is_water[i][j] == 1 {
|
||||
res[i][j] = 0;
|
||||
queue.push_back((i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while let Some((k, l)) = queue.pop_front() {
|
||||
if k > 0 && res[k - 1][l] == i32::MAX {
|
||||
res[k - 1][l] = res[k][l] + 1;
|
||||
queue.push_back((k - 1, l));
|
||||
}
|
||||
if k < n - 1 && res[k + 1][l] == i32::MAX {
|
||||
res[k + 1][l] = res[k][l] + 1;
|
||||
queue.push_back((k + 1, l));
|
||||
}
|
||||
if l > 0 && res[k][l - 1] == i32::MAX {
|
||||
res[k][l - 1] = res[k][l] + 1;
|
||||
queue.push_back((k, l - 1));
|
||||
}
|
||||
|
||||
if l < m - 1 && res[k][l + 1] == i32::MAX {
|
||||
res[k][l + 1] = res[k][l] + 1;
|
||||
queue.push_back((k, l + 1));
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
pub fn first_complete_index(arr: Vec<i32>, mat: Vec<Vec<i32>>) -> i32 {
|
||||
let r = mat.len();
|
||||
let c = mat[0].len();
|
||||
//let mut map = HashMap::new();
|
||||
let mut map2 = vec![(0, 0); r * c + 1];
|
||||
for i in 0..r {
|
||||
for j in 0..c {
|
||||
//map.insert(mat[i][j], (i, j));
|
||||
map2[mat[i][j] as usize] = (i, j);
|
||||
}
|
||||
}
|
||||
|
||||
let mut row_req = vec![0; r];
|
||||
let mut col_req = vec![0; c];
|
||||
for (q, el) in arr.into_iter().enumerate() {
|
||||
let (i, j) = map2[el as usize];
|
||||
row_req[i] += 1;
|
||||
col_req[j] += 1;
|
||||
if row_req[i] == c {
|
||||
return q as i32;
|
||||
}
|
||||
if col_req[j] == r {
|
||||
return q as i32;
|
||||
}
|
||||
}
|
||||
return i32::MAX;
|
||||
}
|
||||
pub fn trap_rain_water_c(height_map: Vec<Vec<i32>>) -> i32 {
|
||||
let rows = height_map.len();
|
||||
let cols = height_map[0].len();
|
||||
let mut queue = VecDeque::new();
|
||||
let mut detail_map: Vec<Vec<Pos>> = Vec::with_capacity(rows);
|
||||
for (i, r) in height_map.iter().enumerate() {
|
||||
let mut row: Vec<Pos> = Vec::with_capacity(cols);
|
||||
for (j, c) in r.iter().enumerate() {
|
||||
let h = *c;
|
||||
let mut new_pos = Pos::new((i, j), h);
|
||||
|
||||
if i == rows - 1 || j == cols - 1 {
|
||||
new_pos.max = (h, true);
|
||||
}
|
||||
|
||||
match (row.is_empty(), detail_map.is_empty()) {
|
||||
(true, true) => {
|
||||
new_pos.max = (h, true);
|
||||
}
|
||||
(true, false) => {
|
||||
if detail_map.last_mut().unwrap()[j].try_red(h) {
|
||||
queue.push_front((i - 1, j));
|
||||
}
|
||||
new_pos.max = (h, true);
|
||||
}
|
||||
(false, true) => {
|
||||
if row.last_mut().unwrap().try_red(h) {
|
||||
queue.push_front((i, j - 1));
|
||||
}
|
||||
new_pos.max = (h, true);
|
||||
}
|
||||
(false, false) => {
|
||||
let max_h = if new_pos.max.1 {
|
||||
h
|
||||
} else {
|
||||
let row_max = row.last().unwrap().max;
|
||||
let detail_max = detail_map.last().unwrap()[j].max;
|
||||
let min_n = std::cmp::min(row_max.0, detail_max.0);
|
||||
std::cmp::max(h, min_n)
|
||||
};
|
||||
new_pos.max = (max_h, h == max_h);
|
||||
|
||||
if row.last_mut().unwrap().try_red(max_h) {
|
||||
queue.push_front((i, j - 1));
|
||||
}
|
||||
|
||||
if detail_map.last_mut().unwrap()[j].try_red(max_h) {
|
||||
queue.push_front((i - 1, j));
|
||||
}
|
||||
/*
|
||||
if row.last().unwrap().shall_update(max_h) {
|
||||
if new_pos.max.1 {
|
||||
queue.push_front((i, j - 1));
|
||||
} else {
|
||||
queue.push_back((i, j - 1));
|
||||
}
|
||||
}
|
||||
if detail_map.last().unwrap()[j].shall_update(max_h) {
|
||||
if new_pos.max.1 {
|
||||
queue.push_front((i - 1, j));
|
||||
} else {
|
||||
queue.push_back((i - 1, j));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
};
|
||||
|
||||
row.push(new_pos);
|
||||
}
|
||||
detail_map.push(row);
|
||||
}
|
||||
/*
|
||||
println!("Q {:?}", queue);
|
||||
println!("________________");
|
||||
for (i, r) in detail_map.iter().enumerate() {
|
||||
for (j, c) in r.iter().enumerate() {
|
||||
println!("{i},{j} {:?}", c);
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
*/
|
||||
/*
|
||||
for i in (1..rows - 1).rev() {
|
||||
for j in (1..cols - 1).rev() {
|
||||
if detail_map[i][j].max.1 {
|
||||
continue;
|
||||
}
|
||||
if detail_map[i][j].max.0 == detail_map[i][j].height {
|
||||
detail_map[i][j].max.1 = true;
|
||||
continue;
|
||||
}
|
||||
let north = detail_map[i + 1][j].max;
|
||||
let south = detail_map[i - 1][j].max;
|
||||
let east = detail_map[i][j + 1].max;
|
||||
let west = detail_map[i][j - 1].max;
|
||||
let min = std::cmp::min(
|
||||
std::cmp::min(north.0, south.0),
|
||||
std::cmp::min(east.0, west.0),
|
||||
);
|
||||
let fix = min == detail_map[i][j].height || (north.1 && south.1 && east.1 && west.1);
|
||||
detail_map[i][j].max = (min, fix);
|
||||
}
|
||||
}*/
|
||||
|
||||
fn neigh_idx(i: usize, j: usize) -> Vec<(usize, usize)> {
|
||||
vec![(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]
|
||||
}
|
||||
|
||||
while let Some((i, j)) = queue.pop_front() {
|
||||
println!("doing {:?} - {:?} -> {:?}", i, j, detail_map[i][j]);
|
||||
//if detail_map[i][j].max.1 {
|
||||
// continue;
|
||||
//}
|
||||
println!("doing {:?} - {:?}", i, j);
|
||||
let (nd, neighbouring_max) = neigh_idx(i, j)
|
||||
.iter()
|
||||
.filter_map(|(x, y)| {
|
||||
let r = detail_map.get(*x).and_then(|r| r.get(*y));
|
||||
println!("{:?}", (r.unwrap().height, r.unwrap().max, x, y));
|
||||
r
|
||||
})
|
||||
.map(|x| x.max)
|
||||
.fold((true, i32::MAX), |acc, x| {
|
||||
(x.1 && acc.0, std::cmp::min(acc.1, x.0))
|
||||
});
|
||||
println!("mins: {:?} - {:?}", nd, neighbouring_max);
|
||||
let new_min = std::cmp::max(neighbouring_max, detail_map[i][j].height);
|
||||
let done = nd || new_min <= detail_map[i][j].height;
|
||||
detail_map[i][j].max = (new_min, done);
|
||||
/*let to_update: Vec<_> = neigh_idx(i, j)
|
||||
.iter()
|
||||
.filter_map(|(x, y)| {
|
||||
detail_map
|
||||
.get(*x)
|
||||
.and_then(|r| r.get(*y))
|
||||
.filter(|p| p.shall_update(new_min))
|
||||
.map(|_| (*x, *y))
|
||||
})
|
||||
.collect();
|
||||
*/
|
||||
for (k, l) in neigh_idx(i, j) {
|
||||
println!("During handling {i} {j}, checking {k} {l}");
|
||||
if detail_map[k][l].try_red(new_min) {
|
||||
println!("During handling {i} {j}, ... checking {k} {l} changed");
|
||||
if done {
|
||||
queue.push_front((k, l));
|
||||
} else {
|
||||
queue.push_back((k, l));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* .for_each(|(p, x, y)| {
|
||||
if x == 17 && y == 12 {
|
||||
println!("{:?} - {:?} -from {:?}", p, new_min, detail_map[i][j]);
|
||||
}
|
||||
if p.shall_update(new_min) {
|
||||
if done {
|
||||
queue.push_front((x, y));
|
||||
} else {
|
||||
queue.push_back((x, y));
|
||||
}
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
println!("________________");
|
||||
for r in detail_map.iter() {
|
||||
for c in r.iter() {
|
||||
println!("{:?} -> {:?}", c, c.max.0 - c.height);
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
|
||||
for i in 0..height_map.len() {
|
||||
println!(" {:?}", height_map[i]);
|
||||
}
|
||||
|
||||
println!("________________");
|
||||
for (i, r) in detail_map.iter().enumerate() {
|
||||
for (j, c) in r.iter().enumerate() {
|
||||
if c.max.0 == c.height {
|
||||
continue;
|
||||
}
|
||||
println!(
|
||||
"Position ({i},{j}): sum_height, water, height ({:?} - {:?} - {:?})",
|
||||
c.max,
|
||||
c.max.0 - c.height,
|
||||
c.height
|
||||
);
|
||||
println!(
|
||||
"Position ({i},{j}): N: {:?} - S: {:?} - E: {:?} - W: {:?}",
|
||||
detail_map[i + 1][j].short(),
|
||||
detail_map[i - 1][j].short(),
|
||||
detail_map[i][j + 1].short(),
|
||||
detail_map[i][j - 1].short()
|
||||
);
|
||||
if neigh_idx(i, j)
|
||||
.into_iter()
|
||||
.any(|(x, y)| detail_map[i][j].max.0 > detail_map[x][y].max.0)
|
||||
{
|
||||
println!("ERROR ({i},{j}) ");
|
||||
}
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
detail_map
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(|x| x.max.0 - x.height)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
struct Pos {
|
||||
position: (usize, usize),
|
||||
max: (i32, bool),
|
||||
height: i32,
|
||||
}
|
||||
|
||||
impl Pos {
|
||||
fn new(position: (usize, usize), height: i32) -> Self {
|
||||
Self {
|
||||
position,
|
||||
height,
|
||||
max: (i32::MAX, false),
|
||||
}
|
||||
}
|
||||
|
||||
fn shall_update(&self, h: i32) -> bool {
|
||||
if self.max.1 {
|
||||
return false;
|
||||
}
|
||||
if self.max.0 == self.height {
|
||||
return false;
|
||||
}
|
||||
return h < self.max.0;
|
||||
}
|
||||
|
||||
fn try_red(&mut self, h: i32) -> bool {
|
||||
if self.max.1 {
|
||||
return false;
|
||||
//panic!("should not be here");
|
||||
}
|
||||
println!("{:?} - changing from {:?} ....", self.position, self.max);
|
||||
let new_heigth = std::cmp::max(std::cmp::min(self.max.0, h), self.height);
|
||||
let changed = new_heigth < self.max.0;
|
||||
self.max = (new_heigth, new_heigth <= self.height);
|
||||
println!("{:?} - changing ...{:?} ", self.position, self.max);
|
||||
changed
|
||||
}
|
||||
|
||||
fn short(&self) -> String {
|
||||
format!(
|
||||
"{:?} - {:?} - {:?}",
|
||||
self.max,
|
||||
self.max.0 - self.height,
|
||||
self.height
|
||||
)
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
struct PosO {
|
||||
coord: (usize, usize),
|
||||
max: (i32, bool),
|
||||
height: i32,
|
||||
north: Option<(i32, bool)>,
|
||||
south: Option<(i32, bool)>,
|
||||
east: Option<(i32, bool)>,
|
||||
west: Option<(i32, bool)>,
|
||||
}
|
||||
|
||||
impl PosO {
|
||||
fn new(coord: (usize, usize), height: i32) -> Self {
|
||||
Self {
|
||||
coord,
|
||||
height,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
enum Dir {
|
||||
L,
|
||||
R,
|
||||
U,
|
||||
D,
|
||||
}
|
||||
impl Dir {
|
||||
fn all() -> Vec<Self> {
|
||||
vec![Dir::L, Dir::R, Dir::U, Dir::D]
|
||||
}
|
||||
fn can_add(&self, cur: (usize, usize), dim: (usize, usize)) -> bool {
|
||||
match self {
|
||||
Dir::U => cur.0 > 0,
|
||||
Dir::D => cur.0 < dim.0 - 1,
|
||||
Dir::L => cur.1 > 0,
|
||||
Dir::R => cur.1 < dim.1 - 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Add<(usize, usize)> for Dir {
|
||||
type Output = (usize, usize);
|
||||
fn add(self, rhs: (usize, usize)) -> Self::Output {
|
||||
match self {
|
||||
Dir::U => (rhs.0 - 1, rhs.1),
|
||||
Dir::D => (rhs.0 + 1, rhs.1),
|
||||
Dir::L => (rhs.0, rhs.1 - 1),
|
||||
Dir::R => (rhs.0, rhs.1 + 1),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Into<Dir> for i32 {
|
||||
fn into(self) -> Dir {
|
||||
match self {
|
||||
4 => Dir::U,
|
||||
1 => Dir::R,
|
||||
2 => Dir::L,
|
||||
3 => Dir::D,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Dir {
|
||||
pub fn go(self, cur: (usize, usize), dim: (usize, usize)) -> Option<(usize, usize)> {
|
||||
match self {
|
||||
Dir::U => {
|
||||
if cur.0 == 0 {
|
||||
None
|
||||
} else {
|
||||
Some((cur.0 - 1, cur.1))
|
||||
}
|
||||
}
|
||||
Dir::D => {
|
||||
if cur.0 == dim.0 - 1 {
|
||||
None
|
||||
} else {
|
||||
Some((cur.0 + 1, cur.1))
|
||||
}
|
||||
}
|
||||
Dir::L => {
|
||||
if cur.1 == 0 {
|
||||
None
|
||||
} else {
|
||||
Some((cur.0, cur.1 - 1))
|
||||
}
|
||||
}
|
||||
Dir::R => {
|
||||
if cur.1 == dim.1 - 1 {
|
||||
None
|
||||
} else {
|
||||
Some((cur.0, cur.1 + 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn min_cost_1(grid: Vec<Vec<i32>>) -> i32 {
|
||||
let mut heap = BinaryHeap::new();
|
||||
let r = grid.len();
|
||||
let c = grid[0].len();
|
||||
let goal = (r - 1, c - 1);
|
||||
let all_dir = vec![Dir::U, Dir::D, Dir::L, Dir::R];
|
||||
let mut known = vec![vec![i32::MAX; c]; r];
|
||||
heap.push(Reverse((0, 0, 0)));
|
||||
while let Some(Reverse((cost, x, y))) = heap.pop() {
|
||||
println!("{:?} - {:?}", cost, (x, y));
|
||||
known[x][y] = cost;
|
||||
if (x, y) == goal {
|
||||
return cost;
|
||||
}
|
||||
let dir: Dir = Into::into(grid[x][y]);
|
||||
all_dir
|
||||
.iter()
|
||||
.filter(|d| **d != dir)
|
||||
.map(|d| (cost + 1, d))
|
||||
.chain(std::iter::once(&dir).map(|d| (cost, d)))
|
||||
.filter_map(|(cost, d)| d.go((x, y), (r, c)).map(|next| (cost, next)))
|
||||
.filter(|(cost, next)| {
|
||||
if known[next.0][next.1] > *cost {
|
||||
known[next.0][next.1] = *cost;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.for_each(|(cost, next)| {
|
||||
heap.push(Reverse((cost, next.0, next.1)));
|
||||
})
|
||||
}
|
||||
|
||||
i32::MAX
|
||||
}
|
||||
|
||||
pub fn min_cost(grid: Vec<Vec<i32>>) -> i32 {
|
||||
let r = grid.len();
|
||||
let c = grid[0].len();
|
||||
let mut heap = VecDeque::with_capacity(r * c);
|
||||
let goal = (r - 1, c - 1);
|
||||
let all_dir = [Dir::U, Dir::D, Dir::L, Dir::R];
|
||||
let mut known = vec![vec![i32::MAX; c]; r];
|
||||
heap.push_back((0, 0, 0));
|
||||
while let Some((cost, x, y)) = heap.pop_front() {
|
||||
println!("{:?} - {:?}", cost, (x, y));
|
||||
known[x][y] = cost;
|
||||
if (x, y) == goal {
|
||||
return cost;
|
||||
}
|
||||
let dir: Dir = Into::into(grid[x][y]);
|
||||
for d in all_dir {
|
||||
if let Some(new_cords) = d.go((x, y), (r, c)) {
|
||||
let (nx, ny) = new_cords;
|
||||
let is_cheap = d == dir;
|
||||
let new_cost = if is_cheap { cost } else { cost + 1 };
|
||||
if known[nx][ny] > new_cost {
|
||||
known[nx][ny] = new_cost;
|
||||
if is_cheap {
|
||||
heap.push_front((new_cost, nx, ny));
|
||||
} else {
|
||||
heap.push_back((new_cost, nx, ny));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i32::MAX
|
||||
}
|
||||
pub fn xor_all_nums(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
|
||||
let mut res = 0;
|
||||
let l2 = nums2.len();
|
||||
if nums1.len() % 2 == 1 {
|
||||
for n in nums2 {
|
||||
res ^= n;
|
||||
}
|
||||
}
|
||||
|
||||
if l2 % 2 == 1 {
|
||||
for n in nums1 {
|
||||
res ^= n;
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
pub fn find_the_prefix_common_array(a: Vec<i32>, b: Vec<i32>) -> Vec<i32> {
|
||||
let n = a.len();
|
||||
a.iter()
|
||||
.zip(b.iter())
|
||||
.scan(
|
||||
(vec![0; n + 1], vec![0; n + 1], Vec::with_capacity(n + 1)),
|
||||
|(ref mut ar, ref mut br, ref mut cr), (an, bn)| {
|
||||
let prev = cr.last().unwrap_or(&0);
|
||||
let add = if an == bn {
|
||||
1
|
||||
} else if ar[*bn as usize] > 0 && br[*an as usize] > 0 {
|
||||
ar[*bn as usize] -= 1;
|
||||
br[*an as usize] -= 1;
|
||||
2
|
||||
} else if ar[*bn as usize] > 0 {
|
||||
ar[*bn as usize] -= 1;
|
||||
ar[*an as usize] += 1;
|
||||
1
|
||||
} else if br[*an as usize] > 0 {
|
||||
br[*an as usize] -= 1;
|
||||
br[*bn as usize] += 1;
|
||||
1
|
||||
} else {
|
||||
ar[*an as usize] += 1;
|
||||
br[*bn as usize] += 1;
|
||||
0
|
||||
};
|
||||
cr.push(prev + add);
|
||||
Some((ar.clone(), br.clone(), cr.clone()))
|
||||
},
|
||||
)
|
||||
.map(|(_, _, a)| a)
|
||||
.last()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
pub fn minimum_length(s: String) -> i32 {
|
||||
let mut freq = [0; 26];
|
||||
for c in s.chars() {
|
||||
freq[c as usize - 'a' as usize] += 1;
|
||||
}
|
||||
freq.into_iter().filter(|&x| x > 0).map(|x| 2 - x % 2).sum()
|
||||
}
|
||||
|
||||
pub fn can_be_valid(s: String, locked: String) -> bool {
|
||||
if s.len() % 2 != 0 {
|
||||
return false;
|
||||
}
|
||||
let mut open = 0;
|
||||
let mut wild = 0;
|
||||
for (b, l) in s.chars().zip(locked.chars()) {
|
||||
if l == '0' {
|
||||
wild += 1;
|
||||
continue;
|
||||
}
|
||||
println!("{:?} - {:?}, {:?}", b, open, wild);
|
||||
match b {
|
||||
'(' => open += 1,
|
||||
')' => {
|
||||
if open > 0 {
|
||||
open -= 1
|
||||
} else if wild > 0 {
|
||||
wild -= 1
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
let mut close = 0;
|
||||
let mut wild = 0;
|
||||
for (b, l) in s
|
||||
.as_bytes()
|
||||
.into_iter()
|
||||
.zip(locked.as_bytes().into_iter())
|
||||
.rev()
|
||||
pub fn divide_array(mut nums: Vec<i32>, k: i32) -> Vec<Vec<i32>> {
|
||||
nums.sort_unstable();
|
||||
let res = nums
|
||||
.chunks(3)
|
||||
.map(|c| c.iter().map(|x| *x).collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>();
|
||||
if res
|
||||
.iter()
|
||||
.any(|x| x.last().unwrap() - x.first().unwrap() > k)
|
||||
{
|
||||
if *l == '0' as u8 {
|
||||
wild += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
match b {
|
||||
val if *val == ')' as u8 => close += 1,
|
||||
val if *val == '(' as u8 => {
|
||||
if close > 0 {
|
||||
close -= 1
|
||||
} else if wild > 0 {
|
||||
wild -= 1
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
vec![]
|
||||
} else {
|
||||
res
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn trap_rain_water(height_map: Vec<Vec<i32>>) -> i32 {
|
||||
let rows = height_map.len();
|
||||
let cols = height_map[0].len();
|
||||
if rows < 3 || cols < 3 {
|
||||
return 0;
|
||||
}
|
||||
let mut queue = BinaryHeap::new();
|
||||
|
||||
let mut map = vec![vec![i32::MAX; cols]; rows];
|
||||
for i in 1..rows - 1 {
|
||||
for (e, f) in [(0, 1), (cols - 1, cols - 2)] {
|
||||
map[i][e] = height_map[i][e];
|
||||
map[i][f] = std::cmp::max(height_map[i][f], height_map[i][e]);
|
||||
queue.push(Reverse((map[i][f], (i, f))));
|
||||
}
|
||||
}
|
||||
for j in 1..cols - 1 {
|
||||
for (e, m) in [(0, 1), (rows - 1, rows - 2)] {
|
||||
map[e][j] = height_map[e][j];
|
||||
map[m][j] = std::cmp::min(map[m][j], std::cmp::max(height_map[m][j], height_map[e][j]));
|
||||
queue.push(Reverse((map[m][j], (m, j))));
|
||||
}
|
||||
}
|
||||
|
||||
let neighbour_indices = |i: usize, j: usize| -> [(usize, usize); 4] {
|
||||
[(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]
|
||||
};
|
||||
|
||||
while let Some(Reverse((new_min, (i, j)))) = queue.pop() {
|
||||
for (k, l) in neighbour_indices(i, j) {
|
||||
let new_neigh_min = std::cmp::max(height_map[k][l], std::cmp::min(map[k][l], new_min));
|
||||
if map[k][l] > new_neigh_min {
|
||||
map[k][l] = new_neigh_min;
|
||||
queue.push(Reverse((new_neigh_min, (k, l))));
|
||||
}
|
||||
}
|
||||
}
|
||||
map.into_iter()
|
||||
.zip(height_map.into_iter())
|
||||
.map(|(l, r)| l.into_iter().zip(r.into_iter()))
|
||||
.flatten()
|
||||
.filter(|x| x.0 != i32::MAX)
|
||||
.map(|x| x.0 - x.1)
|
||||
.sum()
|
||||
#[test]
|
||||
fn test_divide2() {
|
||||
let res = vec![2, 4, 2, 2, 5, 2];
|
||||
assert_eq!(divide_array(res, 2), Vec::<Vec<i32>>::new());
|
||||
}
|
||||
|
||||
pub fn maximum_difference(nums: Vec<i32>) -> i32 {
|
||||
nums.iter()
|
||||
.rev()
|
||||
.scan(i32::MIN, |acc, el| {
|
||||
*acc = (*acc).max(*el);
|
||||
Some(*acc)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.iter()
|
||||
.rev()
|
||||
.skip(1)
|
||||
.zip(nums.iter().scan(i32::MAX, |acc, el| {
|
||||
*acc = (*acc).min(*el);
|
||||
Some(*acc)
|
||||
}))
|
||||
.map(|(max, min)| max - min)
|
||||
.filter(|x| *x > 0)
|
||||
.max()
|
||||
.unwrap_or(-1)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maximum_difference() {
|
||||
assert_eq!(maximum_difference(vec![9, 4, 3, 2]), -1);
|
||||
assert_eq!(maximum_difference(vec![7, 1, 5, 4]), 4);
|
||||
assert_eq!(maximum_difference(vec![1, 5, 2, 10]), 9);
|
||||
assert_eq!(maximum_difference(vec![1, 1, 1]), -1);
|
||||
assert_eq!(maximum_difference(vec![1]), -1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maximum_difference2() {
|
||||
assert_eq!(
|
||||
maximum_difference(vec![
|
||||
999, 997, 980, 976, 948, 940, 938, 928, 924, 917, 907, 907, 881, 878, 864, 862, 859,
|
||||
857, 848, 840, 824, 824, 824, 805, 802, 798, 788, 777, 775, 766, 755, 748, 735, 732,
|
||||
727, 705, 700, 697, 693, 679, 676, 644, 634, 624, 599, 596, 588, 583, 562, 558, 553,
|
||||
539, 537, 536, 509, 491, 485, 483, 454, 449, 438, 425, 403, 368, 345, 327, 287, 285,
|
||||
270, 263, 255, 248, 235, 234, 224, 221, 201, 189, 187, 183, 179, 168, 155, 153, 150,
|
||||
144, 107, 102, 102, 87, 80, 57, 55, 49, 48, 45, 26, 26, 23, 15
|
||||
]),
|
||||
-1
|
||||
);
|
||||
}
|
||||
|
||||
63
src/string/2138DivideStringintoGroupsOfSizek.rs
Normal file
63
src/string/2138DivideStringintoGroupsOfSizek.rs
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
2138. Divide a String Into Groups of Size k
|
||||
Solved
|
||||
Easy
|
||||
Topics
|
||||
premium lock iconCompanies
|
||||
Hint
|
||||
|
||||
A string s can be partitioned into groups of size k using the following procedure:
|
||||
|
||||
The first group consists of the first k characters of the string, the second group consists of the next k characters of the string, and so on. Each element can be a part of exactly one group.
|
||||
For the last group, if the string does not have k characters remaining, a character fill is used to complete the group.
|
||||
|
||||
Note that the partition is done so that after removing the fill character from the last group (if it exists) and concatenating all the groups in order, the resultant string should be s.
|
||||
|
||||
Given the string s, the size of each group k and the character fill, return a string array denoting the composition of every group s has been divided into, using the above procedure.
|
||||
|
||||
|
||||
|
||||
Example 1:
|
||||
|
||||
Input: s = "abcdefghi", k = 3, fill = "x"
|
||||
Output: ["abc","def","ghi"]
|
||||
Explanation:
|
||||
The first 3 characters "abc" form the first group.
|
||||
The next 3 characters "def" form the second group.
|
||||
The last 3 characters "ghi" form the third group.
|
||||
Since all groups can be completely filled by characters from the string, we do not need to use fill.
|
||||
Thus, the groups formed are "abc", "def", and "ghi".
|
||||
|
||||
Example 2:
|
||||
|
||||
Input: s = "abcdefghij", k = 3, fill = "x"
|
||||
Output: ["abc","def","ghi","jxx"]
|
||||
Explanation:
|
||||
Similar to the previous example, we are forming the first three groups "abc", "def", and "ghi".
|
||||
For the last group, we can only use the character 'j' from the string. To complete this group, we add 'x' twice.
|
||||
Thus, the 4 groups formed are "abc", "def", "ghi", and "jxx".
|
||||
|
||||
|
||||
|
||||
Constraints:
|
||||
|
||||
1 <= s.length <= 100
|
||||
s consists of lowercase English letters only.
|
||||
1 <= k <= 100
|
||||
fill is a lowercase English letter.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
pub fn divide_string(s: String, k: i32, fill: char) -> Vec<String> {
|
||||
s.as_bytes()
|
||||
.chunks(k as usize)
|
||||
.map(|c| {
|
||||
let mut chunk: Vec<char> = c.iter().map(|&x| x as char).collect();
|
||||
while chunk.len() < k as usize {
|
||||
chunk.push(fill);
|
||||
}
|
||||
chunk.into_iter().collect()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
5
tmp
Normal file
5
tmp
Normal file
@ -0,0 +1,5 @@
|
||||
poss: 6
|
||||
mult_map: 0 -> [(0, 2), (1, 1), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
|
||||
mult_map: 1 -> [(0, 1), (1, 2), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0)]
|
||||
162
|
||||
Elapsed: 0
|
||||
Loading…
x
Reference in New Issue
Block a user