chore: unwrap one layer
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
4fcc0c57fd
commit
2351dfd0ee
180 changed files with 2 additions and 3 deletions
rs
add-digits.rsbest-time-to-buy-and-sell-stock-iv.rsbinary-tree-inorder-traversal.rsbinary-trees-with-factors.rscan-make-arithmetic-progression-from-sequence.rscheck-if-it-is-a-straight-line.rscomplex-number-multiplication.rscount-vowels-permutation.rsdetonate-the-maximum-bombs.rsfind-mode-in-binary-search-tree.rsfind-pivot-index.rsfind-the-longest-valid-obstacle-course-at-each-position.rsis-graph-bipartite.rskids-with-the-greatest-number-of-candies.rslongest-increasing-subsequence.rslongest-palindromic-subsequence.rsmaximum-level-sum-of-a-binary-tree.rsmaximum-number-of-coins-you-can-get.rsmaximum-running-time-of-n-computers.rsmaximum-value-of-k-coins-from-piles.rsminimum-absolute-difference-in-bst.rsminimum-number-of-vertices-to-reach-all-nodes.rsnumber-of-islands.rsnumber-of-provinces.rspacific-atlantic-water-flow.rspower-of-four.rspredict-the-winner.rsrange-sum-query-immutable.rsreduce-array-size-to-the-half.rsrunning-sum-of-1d-array.rsshortest-path-in-binary-matrix.rssimplify-path.rssmallest-number-in-infinite-set.rssolving-questions-with-brainpower.rssort-characters-by-frequency.rsstamping-the-sequence.rsthe-number-of-weak-characters-in-the-game.rstime-needed-to-inform-all-employees.rsvalidate-stack-sequences.rs
13
rs/add-digits.rs
Normal file
13
rs/add-digits.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
impl Solution {
|
||||
pub fn add_digits(num: i32) -> i32 {
|
||||
if num == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if num % 9 == 0 {
|
||||
return 9;
|
||||
}
|
||||
|
||||
num % 9
|
||||
}
|
||||
}
|
102
rs/best-time-to-buy-and-sell-stock-iv.rs
Normal file
102
rs/best-time-to-buy-and-sell-stock-iv.rs
Normal file
|
@ -0,0 +1,102 @@
|
|||
#[derive(Debug)]
|
||||
struct State {
|
||||
price: i32,
|
||||
profit: i32,
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn new() -> State {
|
||||
State {
|
||||
price: i32::MAX,
|
||||
profit: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&self, previous: &State, price: i32) -> State {
|
||||
let new_price = std::cmp::min(self.price, price - previous.profit);
|
||||
|
||||
State {
|
||||
price: new_price,
|
||||
profit: std::cmp::max(self.profit, price - new_price),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn max_profit(k: i32, prices: Vec<i32>) -> i32 {
|
||||
let mut states: Vec<State> = (0..=k).map(|_| State::new()).collect();
|
||||
|
||||
prices.iter().for_each(|p| {
|
||||
let mut new_states = Vec::from([State::new()]);
|
||||
|
||||
new_states.extend(
|
||||
states
|
||||
.iter()
|
||||
.zip(states.iter().skip(1))
|
||||
.map(|(prev_state, state)| state.update(prev_state, *p)),
|
||||
);
|
||||
|
||||
states = new_states;
|
||||
});
|
||||
|
||||
states.last().expect("No state is present").profit
|
||||
}
|
||||
}
|
||||
struct Solution {}
|
||||
|
||||
fn main() {
|
||||
println!("Hello World!");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests_max_profit {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_small_example() {
|
||||
assert_eq!(Solution::max_profit(2, vec![2, 4, 1]), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bigger_example() {
|
||||
assert_eq!(Solution::max_profit(2, vec![3, 2, 6, 5, 0, 3]), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_small_no_transaction() {
|
||||
assert_eq!(Solution::max_profit(0, vec![2, 4, 1]), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_small_one_transaction() {
|
||||
assert_eq!(Solution::max_profit(1, vec![2, 4, 1]), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bigger_one_transaction() {
|
||||
assert_eq!(Solution::max_profit(1, vec![3, 2, 6, 5, 0, 3]), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_big_all_transactions() {
|
||||
assert_eq!(
|
||||
Solution::max_profit(10, vec![3, 2, 6, 5, 0, 3, 1, 13, 5, 2, 1, 9, 4, 5, 69, 42]),
|
||||
92
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buy_expensive() {
|
||||
assert_eq!(Solution::max_profit(2, vec![2, 3, 14, 15]), 13);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_accumulates_profit() {
|
||||
assert_eq!(Solution::max_profit(5, vec![1, 2, 1, 2, 1, 2, 1, 2, 5]), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_profit_made() {
|
||||
assert_eq!(Solution::max_profit(2, vec![5, 4]), 0);
|
||||
}
|
||||
}
|
40
rs/binary-tree-inorder-traversal.rs
Normal file
40
rs/binary-tree-inorder-traversal.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
// 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::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
impl Solution {
|
||||
fn inorder(values: &mut Vec<i32>, node: Option<&Rc<RefCell<TreeNode>>>) {
|
||||
match node {
|
||||
None => {},
|
||||
Some(n) => {
|
||||
Solution::inorder(values, (*n).borrow().left.as_ref());
|
||||
values.push((*n).borrow().val);
|
||||
Solution::inorder(values, (*n).borrow().right.as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inorder_traversal(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
|
||||
let mut values: Vec<i32> = Vec::new();
|
||||
|
||||
Solution::inorder(&mut values, root.as_ref());
|
||||
|
||||
values
|
||||
}
|
||||
}
|
190
rs/binary-trees-with-factors.rs
Normal file
190
rs/binary-trees-with-factors.rs
Normal file
|
@ -0,0 +1,190 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
impl Solution {
|
||||
const MODULO: i64 = 1000000007;
|
||||
|
||||
fn process_factor(factors: &[i32], j: usize, counts: &mut HashMap<i32, i64>, factor: i32) {
|
||||
counts.insert(factor, 1);
|
||||
|
||||
for i in 0..j {
|
||||
if factor % factors[i] == 0 && counts.contains_key(&(factor / factors[i])) {
|
||||
let previous = *counts.get(&factor).unwrap();
|
||||
|
||||
let left = counts[&factors[i]];
|
||||
let right = counts[&(factor / factors[i])];
|
||||
|
||||
counts.insert(factor, (previous + left * right) % Solution::MODULO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn num_factored_binary_trees(arr: Vec<i32>) -> i32 {
|
||||
let mut factors = arr;
|
||||
factors.sort_unstable();
|
||||
|
||||
let mut counts = HashMap::<i32, i64>::new();
|
||||
for (i, factor) in factors.iter().enumerate() {
|
||||
Solution::process_factor(&factors, i, &mut counts, *factor);
|
||||
}
|
||||
|
||||
counts
|
||||
.values()
|
||||
.fold(0, |acc: i64, &x| (acc + x) % Solution::MODULO) as i32
|
||||
}
|
||||
}
|
||||
|
||||
struct Solution {}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_example_1() {
|
||||
assert_eq!(Solution::num_factored_binary_trees(vec![2, 4]), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_2() {
|
||||
assert_eq!(Solution::num_factored_binary_trees(vec![2, 4, 5, 10]), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_3() {
|
||||
assert_eq!(Solution::num_factored_binary_trees(vec![2, 8]), 2);
|
||||
// assert_eq!(Solution::num_factored_binary_trees(vec![2, 8]), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_forgor_modulo() {
|
||||
assert_eq!(
|
||||
Solution::num_factored_binary_trees(vec![
|
||||
46, 144, 5040, 4488, 544, 380, 4410, 34, 11, 5, 3063808, 5550, 34496, 12, 540, 28,
|
||||
18, 13, 2, 1056, 32710656, 31, 91872, 23, 26, 240, 18720, 33, 49, 4, 38, 37, 1457,
|
||||
3, 799, 557568, 32, 1400, 47, 10, 20774, 1296, 9, 21, 92928, 8704, 29, 2162, 22,
|
||||
1883700, 49588, 1078, 36, 44, 352, 546, 19, 523370496, 476, 24, 6000, 42, 30, 8,
|
||||
16262400, 61600, 41, 24150, 1968, 7056, 7, 35, 16, 87, 20, 2730, 11616, 10912, 690,
|
||||
150, 25, 6, 14, 1689120, 43, 3128, 27, 197472, 45, 15, 585, 21645, 39, 40, 2205,
|
||||
17, 48, 136
|
||||
]),
|
||||
509730797
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wtf() {
|
||||
assert_eq!(
|
||||
Solution::num_factored_binary_trees(vec![
|
||||
60588000, 36158400, 950040, 162450288, 446000100, 1807920, 31590000, 360,
|
||||
166153680, 6, 91213584, 34186320, 915124000, 68600, 6497400, 10, 194304, 951035904,
|
||||
393822000, 23522400, 14400, 821376000, 80, 881118000, 576000, 3660480, 106801200,
|
||||
180690300, 5100, 1573200, 36288000, 38, 197643600, 221852925, 8820, 36000,
|
||||
822294528, 13935240, 236307456, 17409600, 443741760, 62868, 548800000, 25271064,
|
||||
34848, 344137500, 8383500, 186, 45, 100980, 722358000, 63000000, 16442400, 1579500,
|
||||
684, 12970692, 243540, 232560, 149153400, 437400, 16215, 713460, 75524400, 118800,
|
||||
1575, 106920, 10150, 13770000, 33999966, 177811200, 64680, 2880768, 632459520,
|
||||
8675100, 498700800, 213572700, 18657600, 22, 6993, 49, 177147000, 6480, 20,
|
||||
3910368, 85201200, 1764, 120093120, 16022160, 290822400, 6219200, 29376000, 235290,
|
||||
20979000, 5, 384, 959140, 443944800, 11303040, 952560, 47736000, 33404280, 39936,
|
||||
11864320, 144270720, 12868224, 18289152, 87230682, 145860, 262548, 10276500, 12,
|
||||
612, 179010000, 622987200, 108475200, 1012, 60, 14880, 10924200, 2285568,
|
||||
149178000, 1573936, 195695500, 213269760, 24975, 12000, 3706560, 168382080, 114724,
|
||||
87650640, 8019000, 8035200, 8621844, 514500, 155, 132612480, 1676700, 627318720,
|
||||
39330, 17, 926100000, 283360, 69949440, 856575, 4092, 130, 720, 958035000, 5396820,
|
||||
2668, 6606336, 169708000, 2352240, 26, 40608000, 324576, 3220, 4945920, 187697664,
|
||||
350, 3965520, 40500, 9000, 142560, 39580800, 447051000, 19077120, 36605250, 775,
|
||||
19404, 87514000, 2673, 9720, 4942080, 56752500, 118216665, 858, 18225, 3124800,
|
||||
1530, 380160, 24554880, 2762100, 646945200, 173210400, 22376250, 731076192, 161,
|
||||
44705100, 145981440, 18223660, 215424, 878526000, 22883952, 92092, 7306200, 32,
|
||||
2708160, 566957475, 17305344, 119556000, 411402240, 1292544, 454480, 2208,
|
||||
27498240, 249230520, 88058880, 2108, 527800, 455, 49846104, 801900, 252450, 7644,
|
||||
129540320, 2241675, 1330, 71089200, 2709630, 43545600, 497250, 4972968, 826277760,
|
||||
249091200, 68827500, 60900, 271282240, 13910400, 88609950, 46189440, 3088800,
|
||||
582912000, 4284000, 304980000, 32736, 992, 52992, 454545000, 14064960, 72967500,
|
||||
892584000, 61678260, 3410, 49104000, 840931520, 107805600, 200475, 35384580,
|
||||
4289408, 599079390, 777, 465696, 7956000, 540960, 3385200, 8741250, 17748, 2528240,
|
||||
2248480, 83076840, 366282000, 15120000, 6871956, 15586560, 992673792, 367200,
|
||||
65577600, 635796000, 150, 62524000, 7551600, 1716660, 85932, 209986560, 6167826,
|
||||
1557192, 20702500, 157320, 14427072, 553402080, 203290560, 3830112, 1500,
|
||||
120992256, 89280, 66943800, 8937984, 30, 32457600, 75140, 874, 34398000, 390600,
|
||||
955500, 32542560, 51068160, 6624, 545368824, 316461600, 236670, 598067712,
|
||||
97538400, 3240000, 664801200, 6120, 477487296, 445419000, 38318280, 148800, 7,
|
||||
1055600, 9128700, 6472800, 13176240, 535680, 7998, 345960, 1262250, 78693120, 1364,
|
||||
15, 13800, 406000, 42, 23, 703872, 787939152, 24288, 37795758, 6300000, 145704960,
|
||||
124, 46920, 3142656, 31725, 92, 186300, 1470, 73500, 3495250, 196416, 639878400,
|
||||
65800, 1015680, 131176500, 37264500, 243984000, 19227000, 917280, 9384000, 81840,
|
||||
454406400, 795217500, 147420000, 6976800, 14651280, 116, 11960, 153740160,
|
||||
799948800, 5184000, 501686640, 1020, 773500, 145763550, 26417664, 11446380, 13,
|
||||
14817600, 406125720, 7068600, 730667520, 3371004, 2677752, 2692305, 70615314, 1771,
|
||||
388411200, 20175075, 14742000, 139991040, 302400, 40131360, 21740796, 5996025,
|
||||
205615179, 469193472, 23220, 8286300, 19706400, 2812992, 72886425, 3072, 6557760,
|
||||
551779200, 960, 74592, 185427840, 40068864, 883872000, 85250, 3499200, 2210,
|
||||
402772500, 1274, 106260, 4392080, 953146480, 90744192, 132699840, 4270560,
|
||||
361746000, 342720, 673536600, 2418, 234600, 967255800, 34500, 8910, 196040,
|
||||
374190336, 9790200, 694747200, 5385600, 907200, 493426080, 804683880, 13820544,
|
||||
7999488, 4879680, 88400, 13765500, 28, 377, 172339200, 97152, 427680, 41731200,
|
||||
92610, 13950000, 564200, 2520, 74970, 11603592, 16, 18200, 201386250, 474525,
|
||||
531468, 1860, 51840, 677376, 59520, 4457400, 8912376, 6742008, 11013975, 566280,
|
||||
330832, 110707200, 172727100, 382200, 942480, 10200, 3210480, 2033600, 11289564,
|
||||
6667920, 675347400, 79994880, 27676800, 158100, 133722000, 66769920, 332041248, 25,
|
||||
1545600, 21450, 655966080, 11814660, 223200, 4151040, 1016064, 35, 1607040, 924,
|
||||
586333020, 174787200, 63756, 18957120, 788900000, 351900000, 1380, 5441800, 374,
|
||||
44200, 38640, 8307684, 109707264, 2178, 7440, 6577200, 29435, 264600000, 12960000,
|
||||
2646, 891691416, 475656192, 214033920, 431708160, 70340256, 404736, 39104,
|
||||
787059000, 3208500, 220103100, 191268, 66960000, 18500832, 856016640, 173901000,
|
||||
1238688, 157489920, 54782, 550946880, 242573760, 257040, 282720, 117645000,
|
||||
165369600, 13110, 434079360, 9133344, 621000, 174037500, 126960, 6147900,
|
||||
137491200, 29559600, 700, 185220000, 317520000, 200344320, 14036, 26601120,
|
||||
3535488, 3649940, 16240, 61659000, 430848, 779483250, 363528000, 419764800,
|
||||
729933750, 386661600, 111481920, 35700, 6561000, 68695200, 70, 297, 83700, 990,
|
||||
113076810, 461538, 787529952, 4324, 20727, 40350150, 218700, 846720, 540, 29889000,
|
||||
1016600, 277704000, 62734080, 14856192, 210924000, 589248000, 5760, 222393600,
|
||||
30180600, 166059400, 31021056, 98208, 21, 21168, 98208000, 13464, 1555200,
|
||||
16077600, 288, 4332042, 320550912, 204989400, 785664, 67897440, 65472, 16228800,
|
||||
70560, 80352, 8, 9520896, 71280, 4862, 44, 12545280, 657395200, 39, 64152000,
|
||||
283719996, 247443840, 924159600, 20286000, 268065, 138983850, 9300, 5286120,
|
||||
61534200, 496601280, 875033280, 6370, 5940, 364, 29412, 261360, 1248, 477290880,
|
||||
5880, 669600, 82174400, 53568, 483000, 36, 18, 29728512, 12057760, 3046680, 44660,
|
||||
368874000, 167040, 4276800, 83462400, 11050, 638, 34300000, 27, 509110272,
|
||||
437132430, 81200, 33, 6277500, 113601600, 14850, 10789200, 157216500, 20348928,
|
||||
10701900, 365904000, 1728, 1782960, 1255800, 38321400, 3542, 6229872, 40864824,
|
||||
514483200, 43, 1159200, 413100, 1127100, 8019, 198251550, 47, 30950400, 2115, 46,
|
||||
45900, 233280000, 125736, 200508, 5742, 222456, 442520, 245188944, 162288000,
|
||||
5589000, 76923, 2461536, 415457280, 715936320, 179289600, 14826240, 17150000,
|
||||
13759200, 63240, 7001280, 663000, 22776600, 221925825, 920700, 1421000, 1715616,
|
||||
30198960, 1766100, 2480, 290, 460, 1556640, 1015, 145411200, 11350500, 824199480,
|
||||
539028000, 11865150, 882000, 19, 830297000, 159840, 7632800, 81053840, 68250,
|
||||
77873400, 123965952, 164826900, 23040, 347200, 51323580, 30294000, 140777000, 1023,
|
||||
147556500, 273420, 13665960, 2760, 21780, 77552640, 3245760, 341433225, 930, 12740,
|
||||
441, 960498, 184988160, 219240000, 125854344, 13986, 174960, 53978400, 2163168,
|
||||
456840000, 1513400, 179676000, 90810720, 28569600, 4923072, 807003000, 49758720,
|
||||
47404500, 480, 42340320, 837000000, 3, 3720, 15847920, 1400, 1715000, 251160, 198,
|
||||
504708750, 8932000, 6311250, 1458240, 96, 37235712, 911400, 255816, 142084800,
|
||||
39346560, 2384640, 38491200, 1872000, 899640, 14586, 294624, 37, 239760, 469476000,
|
||||
1015200, 531454000, 411840, 36352800, 15367680, 273454272, 63987840, 22416750,
|
||||
24500, 171535, 683384832, 47586240, 82800, 112266, 12746370, 429545025, 875769840,
|
||||
125468160, 74, 39412800, 45904320, 9313920, 1589760, 24, 570240, 72912000, 107880,
|
||||
1758120, 7980, 2614640, 34, 12987000, 3124044, 728640, 21420, 4, 22855680, 21600,
|
||||
99, 11, 203076720, 90132, 687447000, 5049000, 747225, 37620, 13363200, 209265525,
|
||||
171169600, 461039040, 36946, 79197560, 35280, 108100, 22032000, 343062720,
|
||||
29141775, 906782240, 297600, 298378080, 486129600, 979104000, 22151360, 74576700,
|
||||
1647030, 58870, 828100, 1064, 58605120, 12182400, 860288, 41, 62107500, 9,
|
||||
310495680, 71951360, 29, 105995232, 13838, 1617000, 832431600, 328671, 510,
|
||||
3826550, 689018400, 10959300, 48, 3294060, 22720320, 132022800, 24663600, 40, 520,
|
||||
6756750, 429624000, 79497600, 11427840, 489167910, 54734592, 10847520, 887284800,
|
||||
223948800, 735139125, 3478200, 470235, 649152000, 86619456, 932536800, 2976, 675,
|
||||
491756100, 73780, 1142784, 5488560, 1473780, 301693392, 8819902, 88357500, 40392,
|
||||
579600, 457113600, 2, 692841600, 77189112, 49538412, 18086640, 104976000, 35162400,
|
||||
4320, 435, 107892000, 14, 832, 257094000, 345, 323389440, 813440, 13392000, 29760,
|
||||
8391600, 599400, 1713600, 154560, 7380480, 127429200, 198360, 8625, 459345600,
|
||||
13117650, 1309440, 85680, 41972175, 75710880, 87339648, 55296000, 1054, 10098,
|
||||
269414640, 787644000, 34560, 253, 721353600, 28072, 5984, 148764, 84630, 25966080,
|
||||
141120, 46368, 101680, 31, 82197720, 3312400, 2980800, 18247680, 12453120, 9108,
|
||||
3050400
|
||||
]),
|
||||
874417692
|
||||
);
|
||||
}
|
||||
}
|
31
rs/can-make-arithmetic-progression-from-sequence.rs
Normal file
31
rs/can-make-arithmetic-progression-from-sequence.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn can_make_arithmetic_progression(mut arr: Vec<i32>) -> bool {
|
||||
arr.sort();
|
||||
let diffs: Vec<i32> = arr.windows(2).map(|pair| pair[1] - pair[0]).collect();
|
||||
diffs.windows(2).all(|pair| pair[0] == pair[1])
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// Input: arr = [3,5,1]
|
||||
// Output: true
|
||||
// Explanation: We can reorder the elements as [1,3,5] or [5,3,1] with differences 2 and -2 respectively, between each consecutive elements.
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert!(Solution::can_make_arithmetic_progression(vec![3, 5, 1]));
|
||||
}
|
||||
|
||||
// Input: arr = [1,2,4]
|
||||
// Output: false
|
||||
// Explanation: There is no way to reorder the elements to obtain an arithmetic progression.
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert!(!Solution::can_make_arithmetic_progression(vec![2, 4, 1]));
|
||||
}
|
||||
}
|
58
rs/check-if-it-is-a-straight-line.rs
Normal file
58
rs/check-if-it-is-a-straight-line.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
struct Solution {}
|
||||
impl Solution {
|
||||
fn x_diff(a: &[i32], b: &[i32]) -> i32 {
|
||||
a[0] - b[0]
|
||||
}
|
||||
|
||||
fn y_diff(a: &[i32], b: &[i32]) -> i32 {
|
||||
a[1] - b[1]
|
||||
}
|
||||
|
||||
pub fn check_straight_line(coordinates: Vec<Vec<i32>>) -> bool {
|
||||
assert!(coordinates.len() > 1);
|
||||
|
||||
let (dx, dy) = (
|
||||
Solution::x_diff(&coordinates[0], &coordinates[1]),
|
||||
Solution::y_diff(&coordinates[0], &coordinates[1]),
|
||||
);
|
||||
|
||||
coordinates.iter().all(|pt| {
|
||||
dx * Solution::y_diff(pt, &coordinates[0]) == dy * Solution::x_diff(pt, &coordinates[0])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// Input: coordinates = [[1,2],[2,3],[3,4],[4,5],[5,6],[6,7]]
|
||||
// Output: true
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert!(Solution::check_straight_line(vec![
|
||||
vec![1, 2],
|
||||
vec![2, 3],
|
||||
vec![3, 4],
|
||||
vec![4, 5],
|
||||
vec![5, 6],
|
||||
vec![6, 7]
|
||||
]));
|
||||
}
|
||||
|
||||
// Input: coordinates = [[1,1],[2,2],[3,4],[4,5],[5,6],[7,7]]
|
||||
// Output: false
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert!(!Solution::check_straight_line(vec![
|
||||
vec![1, 1],
|
||||
vec![2, 2],
|
||||
vec![3, 4],
|
||||
vec![4, 5],
|
||||
vec![5, 6],
|
||||
vec![7, 7]
|
||||
]));
|
||||
}
|
||||
}
|
42
rs/complex-number-multiplication.rs
Normal file
42
rs/complex-number-multiplication.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Complex {
|
||||
real: i32,
|
||||
imag: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InvalidComplex;
|
||||
|
||||
impl FromStr for Complex {
|
||||
type Err = InvalidComplex;
|
||||
|
||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||
let parts: Vec<&str> = input.split('+').collect();
|
||||
let real = parts[0].parse::<i32>().unwrap();
|
||||
let imag = parts[1].trim_end_matches('i').parse::<i32>().unwrap();
|
||||
|
||||
Ok(Complex { real, imag })
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Complex {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}+{}i", self.real, self.imag)
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn complex_number_multiply(num1: String, num2: String) -> String {
|
||||
let left: Complex = num1.parse().unwrap();
|
||||
let right: Complex = num2.parse().unwrap();
|
||||
|
||||
(Complex {
|
||||
real: left.real * right.real - left.imag * right.imag,
|
||||
imag: left.real * right.imag + left.imag * right.real,
|
||||
})
|
||||
.to_string()
|
||||
}
|
||||
}
|
104
rs/count-vowels-permutation.rs
Normal file
104
rs/count-vowels-permutation.rs
Normal file
|
@ -0,0 +1,104 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
type CacheKey = (i32, char);
|
||||
struct Cache {
|
||||
cache: HashMap<CacheKey, i32>,
|
||||
}
|
||||
|
||||
impl Cache {
|
||||
const MODULO: i32 = 1000000007;
|
||||
|
||||
fn new() -> Cache {
|
||||
let mut cache = HashMap::<CacheKey, i32>::new();
|
||||
|
||||
for c in "aeiou".chars() {
|
||||
cache.insert((1, c), 1);
|
||||
}
|
||||
|
||||
Cache { cache: cache }
|
||||
}
|
||||
|
||||
fn is_precomputed(&self, n: i32) -> bool {
|
||||
self.cache.keys().any(|key| key.0 == n)
|
||||
}
|
||||
|
||||
fn get(&self, n: i32) -> i32 {
|
||||
self.cache
|
||||
.keys()
|
||||
.filter(|key| key.0 == n)
|
||||
.fold(0, |acc, key| {
|
||||
// Since the answer may be too large, return it modulo 10^9 + 7.
|
||||
(acc + self.cache.get(key).unwrap_or(&0)) % Self::MODULO
|
||||
})
|
||||
}
|
||||
|
||||
fn precompute(&mut self, n: i32) {
|
||||
if self.is_precomputed(n) {
|
||||
return;
|
||||
}
|
||||
|
||||
if !self.is_precomputed(n - 1) {
|
||||
self.precompute(n - 1);
|
||||
}
|
||||
|
||||
for (current, continuation) in vec![
|
||||
('a', "e"),
|
||||
('e', "ai"),
|
||||
('i', "aeou"),
|
||||
('o', "iu"),
|
||||
('u', "a"),
|
||||
] {
|
||||
self.cache.insert(
|
||||
(n, current),
|
||||
continuation.chars().fold(0, |acc, vowel| {
|
||||
(acc + self.cache.get(&(n - 1, vowel)).unwrap()) % Self::MODULO
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn count_vowel_permutation(n: i32) -> i32 {
|
||||
let mut cache = Cache::new();
|
||||
cache.precompute(n);
|
||||
|
||||
cache.get(n)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_example_1() {
|
||||
// Input: n = 1
|
||||
// Output: 5
|
||||
// Explanation: All possible strings are: "a", "e", "i" , "o" and "u".
|
||||
assert_eq!(count_vowel_permutation(1), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_2() {
|
||||
// Input: n = 2
|
||||
// Output: 10
|
||||
// Explanation: All possible strings are: All possible strings are: "ae", "ea", "ei", "ia", "ie", "io", "iu", "oi", "ou" and "ua".
|
||||
assert_eq!(count_vowel_permutation(2), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_3() {
|
||||
// Input: n = 5
|
||||
// Output: 68
|
||||
assert_eq!(count_vowel_permutation(5), 68);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_4() {
|
||||
// Input: n = 3
|
||||
// Output: 19
|
||||
assert_eq!(count_vowel_permutation(3), 19);
|
||||
}
|
||||
}
|
118
rs/detonate-the-maximum-bombs.rs
Normal file
118
rs/detonate-the-maximum-bombs.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
|
||||
fn distance(a: (i64, i64), b: (i64, i64)) -> i64 {
|
||||
let (x1, y1) = a;
|
||||
let (x2, y2) = b;
|
||||
|
||||
(x1 - x2).pow(2) + (y1 - y2).pow(2)
|
||||
}
|
||||
|
||||
struct Graph {
|
||||
edges: HashMap<usize, HashSet<usize>>,
|
||||
}
|
||||
|
||||
impl Graph {
|
||||
fn new(bombs: &[Vec<i32>]) -> Self {
|
||||
let mut edges = HashMap::new();
|
||||
|
||||
for (i, bomb) in bombs.iter().enumerate() {
|
||||
edges.insert(i, HashSet::new());
|
||||
let neighbours = edges.get_mut(&i).unwrap();
|
||||
|
||||
let (x, y, r) = (bomb[0], bomb[1], bomb[2]);
|
||||
let rr = (r as i64).pow(2);
|
||||
|
||||
for j in 0..bombs.len() {
|
||||
if i == j {
|
||||
continue;
|
||||
}
|
||||
|
||||
let (x1, y1) = (bombs[j][0], bombs[j][1]);
|
||||
|
||||
if distance((x as i64, y as i64), (x1 as i64, y1 as i64)) <= rr {
|
||||
neighbours.insert(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Self { edges }
|
||||
}
|
||||
|
||||
fn bfs(&self, mut visited: Vec<bool>, u0: usize) -> i32 {
|
||||
let mut found = 0;
|
||||
|
||||
let mut q = VecDeque::new();
|
||||
q.push_back(u0);
|
||||
visited[u0] = true;
|
||||
|
||||
while let Some(u) = q.pop_front() {
|
||||
found += 1;
|
||||
|
||||
for &v in self.edges.get(&u).unwrap_or(&HashSet::new()) {
|
||||
if !visited[v] {
|
||||
q.push_back(v);
|
||||
visited[v] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
found
|
||||
}
|
||||
}
|
||||
|
||||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn maximum_detonation(bombs: Vec<Vec<i32>>) -> i32 {
|
||||
let graph = Graph::new(&bombs);
|
||||
let visited = vec![false; bombs.len()];
|
||||
(0..bombs.len())
|
||||
.map(|u| graph.bfs(visited.clone(), u))
|
||||
.max()
|
||||
.unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(
|
||||
Solution::maximum_detonation(vec![vec![2, 1, 3], vec![6, 1, 4]]),
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert_eq!(
|
||||
Solution::maximum_detonation(vec![vec![1, 1, 5], vec![10, 10, 5]]),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_3() {
|
||||
assert_eq!(
|
||||
Solution::maximum_detonation(vec![
|
||||
vec![1, 2, 3],
|
||||
vec![2, 3, 1],
|
||||
vec![3, 4, 2],
|
||||
vec![4, 5, 3],
|
||||
vec![5, 6, 4]
|
||||
]),
|
||||
5
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regression_1() {
|
||||
assert_eq!(
|
||||
Solution::maximum_detonation(vec![vec![1, 1, 100000], vec![100000, 100000, 1]]),
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
54
rs/find-mode-in-binary-search-tree.rs
Normal file
54
rs/find-mode-in-binary-search-tree.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use std::cell::RefCell;
|
||||
use std::collections::BTreeMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
// 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,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// struct Solution {}
|
||||
impl Solution {
|
||||
pub fn find_mode(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
|
||||
let mut counters: BTreeMap<i32, usize> = BTreeMap::new();
|
||||
|
||||
let mut stack: Vec<Option<Rc<RefCell<TreeNode>>>> = Vec::new();
|
||||
stack.push(root.clone());
|
||||
|
||||
while let Some(node) = stack.pop() {
|
||||
if node.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let node = node.unwrap();
|
||||
let n = node.borrow();
|
||||
|
||||
counters
|
||||
.entry(n.val)
|
||||
.and_modify(|curr| *curr += 1)
|
||||
.or_insert(1);
|
||||
stack.push(n.left.clone());
|
||||
stack.push(n.right.clone());
|
||||
}
|
||||
|
||||
let maximum = *counters.values().max().unwrap();
|
||||
counters
|
||||
.iter()
|
||||
.filter_map(|(&k, &c)| if c == maximum { Some(k) } else { None })
|
||||
.collect()
|
||||
}
|
||||
}
|
20
rs/find-pivot-index.rs
Normal file
20
rs/find-pivot-index.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
impl Solution {
|
||||
pub fn pivot_index(nums: Vec<i32>) -> i32 {
|
||||
let mut from_left: i32 = 0;
|
||||
let mut from_right: i32 = nums.iter().sum();
|
||||
|
||||
for (i, e) in nums.iter().enumerate() {
|
||||
from_right -= e;
|
||||
|
||||
if from_left == from_right {
|
||||
return i.try_into().unwrap();
|
||||
}
|
||||
|
||||
from_left += e;
|
||||
}
|
||||
|
||||
-1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn longest_obstacle_course_at_each_position(obstacles: Vec<i32>) -> Vec<i32> {
|
||||
let size = obstacles.len();
|
||||
|
||||
let mut lengths: Vec<i32> = vec![1; size];
|
||||
let mut longest_increasing: Vec<i32> = vec![];
|
||||
|
||||
for (i, &height) in obstacles.iter().enumerate() {
|
||||
let idx = longest_increasing.partition_point(|&x| x <= height);
|
||||
|
||||
if idx == longest_increasing.len() {
|
||||
longest_increasing.push(height);
|
||||
} else {
|
||||
longest_increasing[idx] = height;
|
||||
}
|
||||
|
||||
lengths[i] = (idx + 1) as i32;
|
||||
}
|
||||
|
||||
lengths
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(
|
||||
Solution::longest_obstacle_course_at_each_position(vec![1, 2, 3, 2]),
|
||||
vec![1, 2, 3, 3]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert_eq!(
|
||||
Solution::longest_obstacle_course_at_each_position(vec![2, 2, 1]),
|
||||
vec![1, 2, 1]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_3() {
|
||||
assert_eq!(
|
||||
Solution::longest_obstacle_course_at_each_position(vec![3, 1, 5, 6, 4, 2]),
|
||||
vec![1, 1, 2, 3, 2, 2]
|
||||
);
|
||||
}
|
||||
}
|
75
rs/is-graph-bipartite.rs
Normal file
75
rs/is-graph-bipartite.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
struct Solution {}
|
||||
impl Solution {
|
||||
fn color(graph: &Vec<Vec<i32>>, start: usize, colors: &mut Vec<i32>) -> bool {
|
||||
let mut q: VecDeque<usize> = VecDeque::new();
|
||||
q.push_back(start);
|
||||
|
||||
while let Some(u) = q.pop_front() {
|
||||
let u_color = colors[u];
|
||||
|
||||
let next_color = (colors[u] + 1) % 2;
|
||||
for v in &graph[u] {
|
||||
let v = *v as usize;
|
||||
match colors[v] {
|
||||
-1 => {
|
||||
colors[v] = next_color;
|
||||
q.push_back(v);
|
||||
}
|
||||
_ => {
|
||||
if colors[v] != next_color {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn is_bipartite(graph: Vec<Vec<i32>>) -> bool {
|
||||
let mut colors = vec![-1; graph.len()];
|
||||
|
||||
for u in 0..graph.len() {
|
||||
if colors[u] != -1 {
|
||||
continue;
|
||||
}
|
||||
|
||||
colors[u] = 0;
|
||||
if !Solution::color(&graph, u, &mut colors) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert!(!Solution::is_bipartite(vec![
|
||||
vec![1, 2, 3],
|
||||
vec![0, 2],
|
||||
vec![0, 1, 3],
|
||||
vec![0, 2]
|
||||
]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert!(Solution::is_bipartite(vec![
|
||||
vec![1, 3],
|
||||
vec![0, 2],
|
||||
vec![1, 3],
|
||||
vec![0, 2]
|
||||
]));
|
||||
}
|
||||
}
|
41
rs/kids-with-the-greatest-number-of-candies.rs
Normal file
41
rs/kids-with-the-greatest-number-of-candies.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn kids_with_candies(candies: Vec<i32>, extra_candies: i32) -> Vec<bool> {
|
||||
let max = *candies.iter().max().unwrap();
|
||||
candies
|
||||
.iter()
|
||||
.map(|candies| candies + extra_candies >= max)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(
|
||||
Solution::kids_with_candies(vec![2, 3, 5, 1, 3], 3),
|
||||
vec![true, true, true, false, true]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert_eq!(
|
||||
Solution::kids_with_candies(vec![4, 2, 1, 1, 2], 1),
|
||||
vec![true, false, false, false, false]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_3() {
|
||||
assert_eq!(
|
||||
Solution::kids_with_candies(vec![12, 1, 12], 10),
|
||||
vec![true, false, true]
|
||||
);
|
||||
}
|
||||
}
|
18
rs/longest-increasing-subsequence.rs
Normal file
18
rs/longest-increasing-subsequence.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use std::cmp::max;
|
||||
|
||||
impl Solution {
|
||||
pub fn length_of_lis(nums: Vec<i32>) -> i32 {
|
||||
let mut dp = Vec::<i32>::new();
|
||||
dp.resize(nums.len(), 1);
|
||||
|
||||
for i in 1..nums.len() {
|
||||
for j in 0..i {
|
||||
if nums[i] > nums[j] {
|
||||
dp[i] = max(dp[i], dp[j] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*dp.iter().max().unwrap()
|
||||
}
|
||||
}
|
45
rs/longest-palindromic-subsequence.rs
Normal file
45
rs/longest-palindromic-subsequence.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
use std::cmp;
|
||||
|
||||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn longest_palindrome_subseq(s: String) -> i32 {
|
||||
let mut longest: Vec<Vec<i32>> = vec![];
|
||||
longest.resize_with(s.len(), || {
|
||||
let mut nested: Vec<i32> = vec![];
|
||||
nested.resize(s.len(), 0);
|
||||
|
||||
nested
|
||||
});
|
||||
|
||||
for i in (0..s.len()).rev() {
|
||||
longest[i][i] = 1;
|
||||
|
||||
for j in i + 1..s.len() {
|
||||
if s.as_bytes()[i] == s.as_bytes()[j] {
|
||||
longest[i][j] = 2 + longest[i + 1][j - 1];
|
||||
} else {
|
||||
longest[i][j] = cmp::max(longest[i + 1][j], longest[i][j - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
longest[0][s.len() - 1]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn with_skip() {
|
||||
assert_eq!(Solution::longest_palindrome_subseq("bbbab".to_owned()), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn without_skip() {
|
||||
assert_eq!(Solution::longest_palindrome_subseq("cbbd".to_owned()), 2);
|
||||
}
|
||||
}
|
60
rs/maximum-level-sum-of-a-binary-tree.rs
Normal file
60
rs/maximum-level-sum-of-a-binary-tree.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
// 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::convert::TryInto;
|
||||
use std::rc::Rc;
|
||||
|
||||
impl Solution {
|
||||
fn max_sum(levels: &mut Vec<i32>, level: usize, root: Option<Rc<RefCell<TreeNode>>>) {
|
||||
if root == None {
|
||||
return;
|
||||
}
|
||||
|
||||
let r = root.unwrap();
|
||||
|
||||
if level >= levels.len() {
|
||||
levels.resize(level + 1, 0);
|
||||
}
|
||||
levels[level] += r.borrow().val;
|
||||
|
||||
Solution::max_sum(levels, level + 1, r.borrow().left.clone());
|
||||
Solution::max_sum(levels, level + 1, r.borrow().right.clone());
|
||||
}
|
||||
|
||||
pub fn max_level_sum(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
|
||||
let mut levels = vec![];
|
||||
|
||||
Solution::max_sum(&mut levels, 0, root);
|
||||
|
||||
levels
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold((0, i32::MIN), |(max_l, max_s), (l, s)| {
|
||||
if *s > max_s {
|
||||
(l + 1, *s)
|
||||
} else {
|
||||
(max_l, max_s)
|
||||
}
|
||||
})
|
||||
.0
|
||||
.try_into()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
14
rs/maximum-number-of-coins-you-can-get.rs
Normal file
14
rs/maximum-number-of-coins-you-can-get.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
impl Solution {
|
||||
pub fn max_coins(piles: Vec<i32>) -> i32 {
|
||||
let mut sorted_piles = piles.clone();
|
||||
sorted_piles.sort();
|
||||
|
||||
sorted_piles
|
||||
.iter()
|
||||
.rev()
|
||||
.skip(1)
|
||||
.step_by(2)
|
||||
.take(piles.len() / 3)
|
||||
.sum()
|
||||
}
|
||||
}
|
17
rs/maximum-running-time-of-n-computers.rs
Normal file
17
rs/maximum-running-time-of-n-computers.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
impl Solution {
|
||||
pub fn max_run_time(n: i32, mut batteries: Vec<i32>) -> i64 {
|
||||
batteries.sort();
|
||||
|
||||
let mut total = batteries.iter().map(|x| *x as u64).sum::<u64>();
|
||||
let mut k: u64 = 0;
|
||||
|
||||
while *batteries.last().unwrap() as u64 > total / (n as u64 - k) {
|
||||
total -= *batteries.last().unwrap() as u64;
|
||||
batteries.pop();
|
||||
|
||||
k += 1;
|
||||
}
|
||||
|
||||
(total / (n as u64 - k)) as i64
|
||||
}
|
||||
}
|
73
rs/maximum-value-of-k-coins-from-piles.rs
Normal file
73
rs/maximum-value-of-k-coins-from-piles.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
use std::cmp;
|
||||
|
||||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn max_value_of_coins(piles: Vec<Vec<i32>>, k: i32) -> i32 {
|
||||
let k = k as usize;
|
||||
|
||||
let mut mem: Vec<Vec<i32>> = vec![];
|
||||
mem.resize_with(piles.len() + 1, || {
|
||||
let mut v = vec![];
|
||||
v.resize(k as usize + 1, 0);
|
||||
v
|
||||
});
|
||||
|
||||
for i in 1..=piles.len() {
|
||||
for max_j in 0..=k {
|
||||
let mut running_sum = 0;
|
||||
|
||||
for j in 0..=cmp::min(piles[i - 1].len(), max_j as usize) {
|
||||
if j > 0 {
|
||||
running_sum += piles[i - 1][j - 1];
|
||||
}
|
||||
mem[i][max_j] = cmp::max(mem[i][max_j], running_sum + mem[i - 1][max_j - j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mem[piles.len()][k]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
let piles = vec![vec![1, 100, 3], vec![7, 8, 9]];
|
||||
let expected = vec![0, 7, 101, 108, 116, 125, 128, 128];
|
||||
|
||||
for (k, right) in expected.iter().enumerate() {
|
||||
assert_eq!(
|
||||
Solution::max_value_of_coins(piles.clone(), k as i32),
|
||||
*right
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_2() {
|
||||
let piles = vec![
|
||||
vec![100],
|
||||
vec![100],
|
||||
vec![100],
|
||||
vec![100],
|
||||
vec![100],
|
||||
vec![100],
|
||||
vec![1, 1, 1, 1, 1, 1, 700],
|
||||
];
|
||||
let expected = vec![
|
||||
0, 100, 200, 300, 400, 500, 600, 706, 806, 906, 1006, 1106, 1206, 1306, 1306,
|
||||
];
|
||||
|
||||
for (k, right) in expected.iter().enumerate() {
|
||||
assert_eq!(
|
||||
Solution::max_value_of_coins(piles.clone(), k as i32),
|
||||
*right
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
64
rs/minimum-absolute-difference-in-bst.rs
Normal file
64
rs/minimum-absolute-difference-in-bst.rs
Normal file
|
@ -0,0 +1,64 @@
|
|||
// 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;
|
||||
use std::rc::Rc;
|
||||
|
||||
struct Result {
|
||||
min: i32,
|
||||
d: i32,
|
||||
max: i32,
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
fn find_min_diff(root: Option<Rc<RefCell<TreeNode>>>) -> Result {
|
||||
match root {
|
||||
None => Result {
|
||||
min: i32::MAX,
|
||||
d: i32::MAX,
|
||||
max: i32::MIN,
|
||||
},
|
||||
Some(r) => {
|
||||
let l_min = Solution::find_min_diff(r.borrow().left.clone());
|
||||
let r_min = Solution::find_min_diff(r.borrow().right.clone());
|
||||
|
||||
let mut current_d = i32::MAX;
|
||||
if l_min.max != i32::MIN {
|
||||
current_d = (r.borrow().val - l_min.max).abs();
|
||||
}
|
||||
if r_min.min != i32::MAX {
|
||||
current_d = cmp::min(current_d, (r_min.min - r.borrow().val).abs());
|
||||
}
|
||||
|
||||
Result {
|
||||
min: cmp::min(l_min.min, r.borrow().val),
|
||||
d: cmp::min(cmp::min(l_min.d, r_min.d), current_d),
|
||||
max: cmp::max(r.borrow().val, r_min.max),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_minimum_difference(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
|
||||
let r = Solution::find_min_diff(root);
|
||||
|
||||
r.d
|
||||
}
|
||||
}
|
19
rs/minimum-number-of-vertices-to-reach-all-nodes.rs
Normal file
19
rs/minimum-number-of-vertices-to-reach-all-nodes.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
impl Solution {
|
||||
pub fn find_smallest_set_of_vertices(n: i32, edges: Vec<Vec<i32>>) -> Vec<i32> {
|
||||
// It should be possible to use topological ordering + BFS, but…
|
||||
|
||||
let mut is_reachable: Vec<bool> = vec![false; n as usize];
|
||||
for dst in edges.iter().map(|edge| edge[1] as usize) {
|
||||
is_reachable[dst] = true;
|
||||
}
|
||||
|
||||
let mut result: Vec<i32> = vec![];
|
||||
for (i, &reachable) in is_reachable.iter().enumerate() {
|
||||
if !reachable {
|
||||
result.push(i as i32);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
92
rs/number-of-islands.rs
Normal file
92
rs/number-of-islands.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
use std::collections::{HashSet, VecDeque};
|
||||
|
||||
type Position = (i32, i32);
|
||||
type Grid = Vec<Vec<char>>;
|
||||
|
||||
impl Solution {
|
||||
fn indices(grid: &Grid) -> impl Iterator<Item = Position> + '_ {
|
||||
(0..grid.len() as i32)
|
||||
.flat_map(move |y| (0..grid[y as usize].len() as i32).map(move |x| (y, x)))
|
||||
}
|
||||
|
||||
fn interesting(grid: &Grid, visited: &HashSet<Position>, p: &Position) -> bool {
|
||||
let (max_y, max_x) = (grid.len() as i32, grid[0].len() as i32);
|
||||
let &(y, x) = p;
|
||||
|
||||
y >= 0
|
||||
&& y < max_y
|
||||
&& x >= 0
|
||||
&& x < max_x
|
||||
&& grid[p.0 as usize][p.1 as usize] != '0'
|
||||
&& !visited.contains(p)
|
||||
}
|
||||
|
||||
fn bfs(grid: &Grid, visited: &mut HashSet<Position>, pos: Position) {
|
||||
let mut queue: VecDeque<Position> = VecDeque::new();
|
||||
queue.push_back(pos);
|
||||
visited.insert(pos);
|
||||
|
||||
while let Some(p) = queue.pop_front() {
|
||||
for d in [-1, 1] {
|
||||
for adjacent in [(p.0 + d, p.1), (p.0, p.1 + d)] {
|
||||
if Solution::interesting(grid, visited, &adjacent) {
|
||||
queue.push_back(adjacent);
|
||||
visited.insert(adjacent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn num_islands(grid: Grid) -> i32 {
|
||||
let mut visited: HashSet<Position> = HashSet::new();
|
||||
|
||||
let mut islands = 0;
|
||||
for (y, x) in Solution::indices(&grid) {
|
||||
if !Solution::interesting(&grid, &visited, &(y, x)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Solution::bfs(&grid, &mut visited, (y, x));
|
||||
islands += 1;
|
||||
}
|
||||
|
||||
islands
|
||||
}
|
||||
}
|
||||
struct Solution {}
|
||||
|
||||
fn main() {
|
||||
println!("Hello World!");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_example_1() {
|
||||
assert_eq!(
|
||||
Solution::num_islands(vec![
|
||||
vec!['1', '1', '1', '1', '0'],
|
||||
vec!['1', '1', '0', '1', '0'],
|
||||
vec!['1', '1', '0', '0', '0'],
|
||||
vec!['0', '0', '0', '0', '0']
|
||||
]),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_2() {
|
||||
assert_eq!(
|
||||
Solution::num_islands(vec![
|
||||
vec!['1', '1', '0', '0', '0'],
|
||||
vec!['1', '1', '0', '0', '0'],
|
||||
vec!['0', '0', '1', '0', '0'],
|
||||
vec!['0', '0', '0', '1', '1']
|
||||
]),
|
||||
3
|
||||
);
|
||||
}
|
||||
}
|
64
rs/number-of-provinces.rs
Normal file
64
rs/number-of-provinces.rs
Normal file
|
@ -0,0 +1,64 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
struct Solution {}
|
||||
impl Solution {
|
||||
fn bfs(graph: &[Vec<i32>], visited: &mut [bool], u0: usize) {
|
||||
let mut q = VecDeque::new();
|
||||
q.push_back(u0);
|
||||
visited[u0] = true;
|
||||
|
||||
while let Some(u) = q.pop_front() {
|
||||
for v in (0..graph.len()).filter(|&v| graph[u][v] != 0) {
|
||||
if visited[v] {
|
||||
continue;
|
||||
}
|
||||
|
||||
q.push_back(v);
|
||||
visited[v] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_circle_num(is_connected: Vec<Vec<i32>>) -> i32 {
|
||||
let mut visited = vec![false; is_connected.len()];
|
||||
|
||||
let mut count = 0;
|
||||
for i in 0..is_connected.len() {
|
||||
if visited[i] {
|
||||
continue;
|
||||
}
|
||||
|
||||
Solution::bfs(&is_connected, &mut visited, i);
|
||||
count += 1;
|
||||
}
|
||||
|
||||
count
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]]
|
||||
// Output: 2
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(
|
||||
Solution::find_circle_num(vec![vec![1, 1, 0], vec![1, 1, 0], vec![0, 0, 1]]),
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
// Input: isConnected = [[1,0,0],[0,1,0],[0,0,1]]
|
||||
// Output: 3
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert_eq!(
|
||||
Solution::find_circle_num(vec![vec![1, 0, 0], vec![0, 1, 0], vec![0, 0, 1]]),
|
||||
3
|
||||
);
|
||||
}
|
||||
}
|
246
rs/pacific-atlantic-water-flow.rs
Normal file
246
rs/pacific-atlantic-water-flow.rs
Normal file
|
@ -0,0 +1,246 @@
|
|||
use std::{collections::VecDeque, ops::BitOr};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
enum Reachable {
|
||||
None = 0x0,
|
||||
Pacific = 0x1,
|
||||
Atlantic = 0x2,
|
||||
Both = 0x3,
|
||||
}
|
||||
|
||||
impl Reachable {
|
||||
fn new(y: usize, x: usize, max_y: usize, max_x: usize) -> Reachable {
|
||||
let reaches_pacific = y == 0 || x == 0;
|
||||
let reaches_atlantic = y == max_y - 1 || x == max_x - 1;
|
||||
|
||||
match (reaches_pacific, reaches_atlantic) {
|
||||
(true, true) => Reachable::Both,
|
||||
(true, _) => Reachable::Pacific,
|
||||
(_, true) => Reachable::Atlantic,
|
||||
(_, _) => Reachable::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for Reachable {
|
||||
fn from(u: u8) -> Self {
|
||||
match u {
|
||||
0 => Reachable::None,
|
||||
1 => Reachable::Pacific,
|
||||
2 => Reachable::Atlantic,
|
||||
3 => Reachable::Both,
|
||||
_ => panic!("Invalid conversion"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Reachable> for u8 {
|
||||
fn from(r: Reachable) -> Self {
|
||||
match r {
|
||||
Reachable::None => 0,
|
||||
Reachable::Pacific => 1,
|
||||
Reachable::Atlantic => 2,
|
||||
Reachable::Both => 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BitOr for Reachable {
|
||||
type Output = Reachable;
|
||||
|
||||
fn bitor(self, rhs: Self) -> Self::Output {
|
||||
let (lhs, rhs): (u8, u8) = (self.into(), rhs.into());
|
||||
(lhs | rhs).into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum State {
|
||||
Unvisited,
|
||||
Queued,
|
||||
Visited,
|
||||
}
|
||||
|
||||
struct Vertex {
|
||||
height: i32,
|
||||
reaches: Reachable,
|
||||
state: State,
|
||||
}
|
||||
|
||||
struct Graph {
|
||||
vertices: Vec<Vec<Vertex>>,
|
||||
max_y: usize,
|
||||
max_x: usize,
|
||||
}
|
||||
|
||||
impl Graph {
|
||||
pub fn new(heights: &Vec<Vec<i32>>) -> Graph {
|
||||
let max_y = heights.len();
|
||||
let max_x = heights[0].len();
|
||||
|
||||
Graph {
|
||||
vertices: heights
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(y, row)| {
|
||||
row.iter()
|
||||
.enumerate()
|
||||
.map(|(x, h)| Vertex {
|
||||
height: *h,
|
||||
reaches: Reachable::new(y, x, max_y, max_x),
|
||||
state: State::Unvisited,
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect(),
|
||||
max_y,
|
||||
max_x,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vertices(&self) -> &Vec<Vec<Vertex>> {
|
||||
&self.vertices
|
||||
}
|
||||
|
||||
fn _vertex(&mut self, y: i32, x: i32) -> Option<&mut Vertex> {
|
||||
if y >= 0 && y < self.max_y as i32 && x >= 0 && x < self.max_x as i32 {
|
||||
Some(&mut self.vertices[y as usize][x as usize])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn _run_bfs(&mut self, q: &mut VecDeque<(i32, i32)>) {
|
||||
q.iter().for_each(|&(y, x)| {
|
||||
self._vertex(y, x).unwrap().state = State::Queued;
|
||||
});
|
||||
|
||||
while let Some((y, x)) = q.pop_front() {
|
||||
self._vertex(y, x).unwrap().state = State::Visited;
|
||||
let h = self._vertex(y, x).unwrap().height;
|
||||
let r = self._vertex(y, x).unwrap().reaches;
|
||||
|
||||
for d in [-1, 1] {
|
||||
for (next_y, next_x) in [(y + d, x), (y, x + d)] {
|
||||
if let Some(v) = self._vertex(next_y, next_x) {
|
||||
if matches!(v.state, State::Unvisited) && h <= v.height {
|
||||
q.push_back((next_y, next_x));
|
||||
v.state = State::Queued;
|
||||
v.reaches = r | v.reaches;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn _reset(&mut self) {
|
||||
for y in 0..self.max_y {
|
||||
for x in 0..self.max_x {
|
||||
self.vertices[y][x].state = State::Unvisited;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bfs(&mut self) {
|
||||
// Run BFS from Pacific Ocean
|
||||
self._run_bfs(&mut VecDeque::from(
|
||||
(0..self.max_x)
|
||||
.map(|x| (0_i32, x as i32))
|
||||
.chain((0..self.max_y).map(|y| (y as i32, 0_i32)))
|
||||
.collect::<Vec<(i32, i32)>>(),
|
||||
));
|
||||
|
||||
// Reset the visited
|
||||
self._reset();
|
||||
|
||||
// Run BFS from Atlantic Ocean
|
||||
self._run_bfs(&mut VecDeque::from(
|
||||
(0..self.max_x)
|
||||
.map(|x| (self.max_y as i32 - 1, x as i32))
|
||||
.chain((0..self.max_y).map(|y| (y as i32, self.max_x as i32 - 1)))
|
||||
.collect::<Vec<(i32, i32)>>(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn pacific_atlantic(heights: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
|
||||
let mut g = Graph::new(&heights);
|
||||
g.bfs();
|
||||
|
||||
g.vertices().iter().for_each(|row| {
|
||||
row.iter().for_each(|v| {
|
||||
print!("{:?} ", v.reaches);
|
||||
});
|
||||
|
||||
println!();
|
||||
});
|
||||
|
||||
g.vertices()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(y, row)| {
|
||||
row.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, v)| matches!(v.reaches, Reachable::Both))
|
||||
.map(move |(x, _)| vec![y as i32, x as i32])
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
struct Solution {}
|
||||
|
||||
fn main() {
|
||||
println!("Hello World!");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_example_1() {
|
||||
assert_eq!(
|
||||
Solution::pacific_atlantic(vec![
|
||||
vec![1, 2, 2, 3, 5],
|
||||
vec![3, 2, 3, 4, 4],
|
||||
vec![2, 4, 5, 3, 1],
|
||||
vec![6, 7, 1, 4, 5],
|
||||
vec![5, 1, 1, 2, 4]
|
||||
]),
|
||||
vec![
|
||||
vec![0, 4],
|
||||
vec![1, 3],
|
||||
vec![1, 4],
|
||||
vec![2, 2],
|
||||
vec![3, 0],
|
||||
vec![3, 1],
|
||||
vec![4, 0]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_2() {
|
||||
assert_eq!(Solution::pacific_atlantic(vec![vec![1]]), vec![vec![0, 0]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrong() {
|
||||
assert_eq!(
|
||||
Solution::pacific_atlantic(vec![vec![3, 3, 3], vec![3, 1, 3], vec![0, 2, 4]]),
|
||||
vec![
|
||||
vec![0, 0],
|
||||
vec![0, 1],
|
||||
vec![0, 2],
|
||||
vec![1, 0],
|
||||
vec![1, 2],
|
||||
vec![2, 0],
|
||||
vec![2, 1],
|
||||
vec![2, 2]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
15
rs/power-of-four.rs
Normal file
15
rs/power-of-four.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
impl Solution {
|
||||
pub fn is_power_of_four(n: i32) -> bool {
|
||||
if n == 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut x = n;
|
||||
|
||||
while x % 4 == 0 {
|
||||
x >>= 2;
|
||||
}
|
||||
|
||||
x == 1
|
||||
}
|
||||
}
|
22
rs/predict-the-winner.rs
Normal file
22
rs/predict-the-winner.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use std::cmp::max;
|
||||
|
||||
impl Solution {
|
||||
pub fn predict_the_winner(nums: Vec<i32>) -> bool {
|
||||
let mut dp = vec![vec![0; nums.len()]; nums.len()];
|
||||
|
||||
// initialize
|
||||
for (i, &num) in nums.iter().enumerate() {
|
||||
dp[i][i] = num;
|
||||
}
|
||||
|
||||
// carry on the DP
|
||||
for d in 1..nums.len() {
|
||||
for l in 0..nums.len() - d {
|
||||
let r = l + d;
|
||||
dp[l][r] = max(nums[l] - dp[l + 1][r], nums[r] - dp[l][r - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
dp[0][nums.len() - 1] >= 0
|
||||
}
|
||||
}
|
45
rs/range-sum-query-immutable.rs
Normal file
45
rs/range-sum-query-immutable.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
#[derive(Debug)]
|
||||
struct NumArray {
|
||||
prefix_sums: Vec<i32>,
|
||||
}
|
||||
|
||||
impl NumArray {
|
||||
fn new(nums: Vec<i32>) -> Self {
|
||||
let mut total = nums.iter().sum::<i32>();
|
||||
|
||||
let mut prefix_sums: Vec<i32> = nums
|
||||
.iter()
|
||||
.scan(total, |total, &x| {
|
||||
let prev = *total;
|
||||
*total -= x;
|
||||
|
||||
Some(prev)
|
||||
})
|
||||
.collect();
|
||||
prefix_sums.push(0);
|
||||
|
||||
Self { prefix_sums }
|
||||
}
|
||||
|
||||
fn sum_range(&self, left: i32, right: i32) -> i32 {
|
||||
self.prefix_sums[left as usize] - self.prefix_sums[right as usize + 1]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
let num_arr = NumArray::new(vec![-2, 0, 3, -5, 2, -1]);
|
||||
|
||||
dbg!("{:?}", &num_arr);
|
||||
|
||||
assert_eq!(num_arr.sum_range(0, 2), 1);
|
||||
assert_eq!(num_arr.sum_range(2, 5), -1);
|
||||
assert_eq!(num_arr.sum_range(0, 5), -3);
|
||||
}
|
||||
}
|
89
rs/reduce-array-size-to-the-half.rs
Normal file
89
rs/reduce-array-size-to-the-half.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
struct Accumulator {
|
||||
removed: usize,
|
||||
removed_distinct: i32,
|
||||
}
|
||||
|
||||
impl Accumulator {
|
||||
fn new() -> Accumulator {
|
||||
Accumulator { removed: 0, removed_distinct: 0 }
|
||||
}
|
||||
|
||||
fn update(self, length: usize, count: i32) -> Accumulator {
|
||||
if 2 * self.removed < length {
|
||||
Accumulator {
|
||||
removed: self.removed + count as usize,
|
||||
removed_distinct: self.removed_distinct + 1,
|
||||
}
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn min_set_size(arr: Vec<i32>) -> i32 {
|
||||
let mut counts = arr
|
||||
.iter()
|
||||
.fold(BTreeMap::<i32, i32>::new(), |mut acc: BTreeMap<i32, i32>, x: &i32| {
|
||||
let current = *acc.get(x).unwrap_or(&0);
|
||||
acc.insert(*x, current + 1);
|
||||
|
||||
acc
|
||||
})
|
||||
.iter()
|
||||
.map(|(&x, &y)| { (x, y) })
|
||||
.collect::<Vec<(i32, i32)>>();
|
||||
|
||||
counts
|
||||
.sort_by(|&(_, y0), &(_, y1)| y1.cmp(&y0));
|
||||
|
||||
counts
|
||||
.iter()
|
||||
.fold(Accumulator::new(), |acc, &(_, count)| {
|
||||
acc.update(arr.len(), count)
|
||||
}).removed_distinct
|
||||
}
|
||||
}
|
||||
|
||||
struct Solution {}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_example() {
|
||||
assert_eq!(Solution::min_set_size(vec![3, 3, 3, 3, 5, 5, 5, 2, 2, 7]), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_same() {
|
||||
assert_eq!(Solution::min_set_size(vec![7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_exact_half() {
|
||||
assert_eq!(Solution::min_set_size(vec![1, 1, 2, 2]), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_more_than_half() {
|
||||
assert_eq!(Solution::min_set_size(vec![1, 1, 2, 2, 2]), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_distinct() {
|
||||
assert_eq!(Solution::min_set_size(vec![1, 2, 3, 4, 5, 6, 7]), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_big_distinct() {
|
||||
assert_eq!(Solution::min_set_size((1..=100).rev().collect()), 50);
|
||||
}
|
||||
}
|
8
rs/running-sum-of-1d-array.rs
Normal file
8
rs/running-sum-of-1d-array.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
impl Solution {
|
||||
pub fn running_sum(nums: Vec<i32>) -> Vec<i32> {
|
||||
nums.iter().scan(0, |s, &x| {
|
||||
*s = *s + x;
|
||||
Some(*s)
|
||||
}).collect()
|
||||
}
|
||||
}
|
106
rs/shortest-path-in-binary-matrix.rs
Normal file
106
rs/shortest-path-in-binary-matrix.rs
Normal file
|
@ -0,0 +1,106 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::convert::TryInto;
|
||||
|
||||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn shortest_path_binary_matrix(grid: Vec<Vec<i32>>) -> i32 {
|
||||
let n = grid.len();
|
||||
|
||||
// create an array of distances
|
||||
let mut distances = grid.clone();
|
||||
for y in 0..n {
|
||||
for x in 0..n {
|
||||
distances[y][x] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the start with an initial distance
|
||||
let mut q: VecDeque<(usize, usize)> = VecDeque::new();
|
||||
if grid[0][0] == 0 {
|
||||
distances[0][0] = 1;
|
||||
q.push_back((0, 0));
|
||||
}
|
||||
|
||||
while let Some((y, x)) = q.pop_front() {
|
||||
if (y, x) == (n - 1, n - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (next_y, next_x) in (-1_isize..=1)
|
||||
.flat_map(|dy| (-1_isize..=1).map(move |dx| (dy, dx)))
|
||||
.map(|(dy, dx)| (y as isize + dy, x as isize + dx))
|
||||
.filter(|&(next_y, next_x)| {
|
||||
(next_y, next_x) != (y as isize, x as isize)
|
||||
&& next_y >= 0
|
||||
&& next_y < n.try_into().unwrap()
|
||||
&& next_x >= 0
|
||||
&& next_x < n.try_into().unwrap()
|
||||
})
|
||||
{
|
||||
let (next_y, next_x) = (next_y as usize, next_x as usize);
|
||||
|
||||
if distances[next_y][next_x] == -1 && grid[next_y][next_x] == 0 {
|
||||
distances[next_y][next_x] = distances[y][x] + 1;
|
||||
q.push_back((
|
||||
(next_y as isize).try_into().unwrap(),
|
||||
(next_x as isize).try_into().unwrap(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
distances[n - 1][n - 1]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(
|
||||
Solution::shortest_path_binary_matrix(vec![vec![0, 1], vec![1, 0]]),
|
||||
2
|
||||
);
|
||||
assert_eq!(
|
||||
Solution::shortest_path_binary_matrix(vec![vec![0, 0, 0], vec![1, 1, 0], vec![1, 1, 0]]),
|
||||
4
|
||||
);
|
||||
assert_eq!(
|
||||
Solution::shortest_path_binary_matrix(vec![vec![1, 0, 0], vec![1, 1, 0], vec![1, 1, 0]]),
|
||||
-1
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(
|
||||
Solution::shortest_path_binary_matrix(vec![vec![0, 1], vec![1, 0]]),
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert_eq!(
|
||||
Solution::shortest_path_binary_matrix(vec![
|
||||
vec![0, 0, 0],
|
||||
vec![1, 1, 0],
|
||||
vec![1, 1, 0]
|
||||
]),
|
||||
4
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_3() {
|
||||
assert_eq!(
|
||||
Solution::shortest_path_binary_matrix(vec![
|
||||
vec![1, 0, 0],
|
||||
vec![1, 1, 0],
|
||||
vec![1, 1, 0]
|
||||
]),
|
||||
-1
|
||||
);
|
||||
}
|
||||
}
|
49
rs/simplify-path.rs
Normal file
49
rs/simplify-path.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn simplify_path(path: String) -> String {
|
||||
let mut simplified_path = Vec::<&str>::new();
|
||||
|
||||
path.split('/').for_each(|seg| {
|
||||
if seg.is_empty() || seg == "." {
|
||||
return;
|
||||
}
|
||||
|
||||
if seg == ".." {
|
||||
simplified_path.pop();
|
||||
return;
|
||||
}
|
||||
|
||||
simplified_path.push(seg);
|
||||
});
|
||||
|
||||
"/".to_owned() + &simplified_path.join("/")
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn one_directory() {
|
||||
assert_eq!(
|
||||
Solution::simplify_path("/home/".to_owned()),
|
||||
"/home".to_owned()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn just_root() {
|
||||
assert_eq!(Solution::simplify_path("/../".to_owned()), "/".to_owned());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn consecutive_slashes() {
|
||||
assert_eq!(
|
||||
Solution::simplify_path("/home//foo/".to_owned()),
|
||||
"/home/foo".to_owned()
|
||||
);
|
||||
}
|
||||
}
|
69
rs/smallest-number-in-infinite-set.rs
Normal file
69
rs/smallest-number-in-infinite-set.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
use std::collections::BTreeSet;
|
||||
|
||||
struct SmallestInfiniteSet {
|
||||
smaller: BTreeSet<i32>,
|
||||
next_infinite: i32,
|
||||
}
|
||||
|
||||
/**
|
||||
* `&self` means the method takes an immutable reference.
|
||||
* If you need a mutable reference, change it to `&mut self` instead.
|
||||
*/
|
||||
impl SmallestInfiniteSet {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
smaller: BTreeSet::new(),
|
||||
next_infinite: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn pop_smallest(&mut self) -> i32 {
|
||||
if let Some(&m) = self.smaller.iter().min() {
|
||||
self.smaller.remove(&m);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
self.next_infinite += 1;
|
||||
self.next_infinite - 1
|
||||
}
|
||||
|
||||
fn add_back(&mut self, num: i32) {
|
||||
if num >= self.next_infinite {
|
||||
return;
|
||||
}
|
||||
|
||||
self.smaller.insert(num);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Your SmallestInfiniteSet object will be instantiated and called as such:
|
||||
* let obj = SmallestInfiniteSet::new();
|
||||
* let ret_1: i32 = obj.pop_smallest();
|
||||
* obj.add_back(num);
|
||||
*/
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
let mut s = SmallestInfiniteSet::new();
|
||||
|
||||
s.add_back(2);
|
||||
|
||||
assert_eq!(s.pop_smallest(), 1);
|
||||
assert_eq!(s.pop_smallest(), 2);
|
||||
assert_eq!(s.pop_smallest(), 3);
|
||||
|
||||
s.add_back(1);
|
||||
|
||||
assert_eq!(s.pop_smallest(), 1);
|
||||
assert_eq!(s.pop_smallest(), 4);
|
||||
assert_eq!(s.pop_smallest(), 5);
|
||||
}
|
||||
}
|
71
rs/solving-questions-with-brainpower.rs
Normal file
71
rs/solving-questions-with-brainpower.rs
Normal file
|
@ -0,0 +1,71 @@
|
|||
use std::cmp;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Question {
|
||||
answered: i64,
|
||||
skipped: i64,
|
||||
}
|
||||
|
||||
impl Question {
|
||||
fn get_with_offset(stack: &Vec<Self>, offset: i64) -> i64 {
|
||||
let i = stack.len() as i64 - offset - 1;
|
||||
if i < 0 || i >= stack.len() as i64 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
stack[i as usize].get()
|
||||
}
|
||||
|
||||
pub fn new(q: &[i32], stack: &Vec<Self>) -> Self {
|
||||
Self {
|
||||
answered: q[0] as i64 + Self::get_with_offset(stack, q[1].into()),
|
||||
skipped: Self::get_with_offset(stack, 0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> i64 {
|
||||
cmp::max(self.answered, self.skipped)
|
||||
}
|
||||
}
|
||||
|
||||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn most_points(questions: Vec<Vec<i32>>) -> i64 {
|
||||
let mut stack: Vec<Question> = vec![];
|
||||
|
||||
for input_q in questions.iter().rev() {
|
||||
stack.push(Question::new(&input_q, &stack));
|
||||
}
|
||||
|
||||
stack.last().unwrap().get()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_example_1() {
|
||||
assert_eq!(
|
||||
Solution::most_points(vec![vec![3, 2], vec![4, 3], vec![4, 4], vec![2, 5]]),
|
||||
5
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_2() {
|
||||
assert_eq!(
|
||||
Solution::most_points(vec![
|
||||
vec![1, 1],
|
||||
vec![2, 2],
|
||||
vec![3, 3],
|
||||
vec![4, 4],
|
||||
vec![5, 5]
|
||||
]),
|
||||
7
|
||||
);
|
||||
}
|
||||
}
|
18
rs/sort-characters-by-frequency.rs
Normal file
18
rs/sort-characters-by-frequency.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use std::cmp::Reverse;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
impl Solution {
|
||||
pub fn frequency_sort(s: String) -> String {
|
||||
let mut freqs: BTreeMap<_, usize> = BTreeMap::new();
|
||||
|
||||
s.as_str().chars().for_each(|c| {
|
||||
let current = freqs.get(&c).unwrap_or(&0);
|
||||
freqs.insert(c, 1 + current);
|
||||
});
|
||||
|
||||
let mut frequencies: Vec<_> = freqs.iter().collect();
|
||||
frequencies.sort_by_key(|&(_, count)| Reverse(count));
|
||||
|
||||
frequencies.iter().fold(String::new(), |s, (c, count)| s + &c.to_string().repeat(**count))
|
||||
}
|
||||
}
|
86
rs/stamping-the-sequence.rs
Normal file
86
rs/stamping-the-sequence.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
impl Solution {
|
||||
fn can_stamp(stamp: &Vec<char>, tape: &Vec<char>, i: usize) -> bool {
|
||||
!Solution::is_fully_stamped_section(stamp.len(), &tape, i)
|
||||
&& (0..stamp.len())
|
||||
.map(|j| (stamp[j], tape[i + j]))
|
||||
.all(|(s, t)| s == t || t == '?')
|
||||
}
|
||||
|
||||
fn is_fully_stamped_section(length: usize, tape: &Vec<char>, i: usize) -> bool {
|
||||
(i..i + length).all(|j| tape[j] == '?')
|
||||
}
|
||||
|
||||
fn stamp_tape(length: usize, tape: &mut Vec<char>, i: usize) {
|
||||
(i..i + length).for_each(|j| {
|
||||
tape[j] = '?';
|
||||
})
|
||||
}
|
||||
|
||||
pub fn moves_to_stamp(stamp: String, target: String) -> Vec<i32> {
|
||||
// convert stamp to usable interpretation
|
||||
let stamp: Vec<char> = stamp.chars().collect();
|
||||
|
||||
// convert target to a mutable array of characters
|
||||
let mut tape: Vec<char> = target.chars().collect();
|
||||
|
||||
// keep track of stamped indices
|
||||
let mut stamped: Vec<i32> = Vec::new();
|
||||
|
||||
// go over and try to stamp while possible
|
||||
let mut has_changed = true;
|
||||
while has_changed && stamped.len() <= 10 * tape.len() {
|
||||
has_changed = false;
|
||||
|
||||
(0..tape.len() + 1 - stamp.len()).for_each(|i| {
|
||||
if Solution::can_stamp(&stamp, &tape, i) {
|
||||
Solution::stamp_tape(stamp.len(), &mut tape, i);
|
||||
stamped.push(i as i32);
|
||||
has_changed = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if stamped.len() > 10 * tape.len()
|
||||
|| !Solution::is_fully_stamped_section(tape.len(), &tape, 0)
|
||||
{
|
||||
stamped.clear();
|
||||
}
|
||||
|
||||
stamped.reverse();
|
||||
stamped
|
||||
}
|
||||
}
|
||||
struct Solution {}
|
||||
|
||||
fn main() {
|
||||
println!("Hello World!");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_example() {
|
||||
assert_eq!(
|
||||
Solution::moves_to_stamp("abc".to_string(), "ababc".to_string()),
|
||||
vec![0, 2]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_another_example() {
|
||||
assert_eq!(
|
||||
Solution::moves_to_stamp("abca".to_string(), "aabcaca".to_string()),
|
||||
vec![0, 3, 1]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unusable_stamp() {
|
||||
assert_eq!(
|
||||
Solution::moves_to_stamp("stamp".to_string(), "tamps".to_string()),
|
||||
vec![]
|
||||
);
|
||||
}
|
||||
}
|
125
rs/the-number-of-weak-characters-in-the-game.rs
Normal file
125
rs/the-number-of-weak-characters-in-the-game.rs
Normal file
|
@ -0,0 +1,125 @@
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct Property {
|
||||
attack: i32,
|
||||
defense: i32,
|
||||
}
|
||||
|
||||
impl Property {
|
||||
fn is_weak(&self, rhs: &Property) -> bool {
|
||||
self.attack < rhs.attack && self.defense < rhs.defense
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Vec<i32>> for Property {
|
||||
fn from(v: &Vec<i32>) -> Self {
|
||||
Self {
|
||||
attack: v[0],
|
||||
defense: v[1],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Property {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
match self.attack.partial_cmp(&other.attack) {
|
||||
Some(core::cmp::Ordering::Equal) => other.defense.partial_cmp(&self.defense),
|
||||
ord => ord,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Property {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
if self.attack != other.attack {
|
||||
self.attack.cmp(&other.attack)
|
||||
} else {
|
||||
other.defense.cmp(&self.defense)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Acc {
|
||||
max: i32,
|
||||
count: i32,
|
||||
}
|
||||
|
||||
impl Acc {
|
||||
fn new(m: i32) -> Acc {
|
||||
Acc { max: m, count: 0 }
|
||||
}
|
||||
|
||||
fn update(self, p: &Property) -> Acc {
|
||||
if p.defense < self.max {
|
||||
Acc {
|
||||
max: self.max,
|
||||
count: self.count + 1,
|
||||
}
|
||||
} else {
|
||||
Acc {
|
||||
max: p.defense,
|
||||
count: self.count,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Solution {
|
||||
pub fn number_of_weak_characters(properties: Vec<Vec<i32>>) -> i32 {
|
||||
let mut properties: Vec<Property> = properties.iter().map(From::from).collect();
|
||||
properties.sort();
|
||||
|
||||
properties
|
||||
.iter()
|
||||
.rfold(Acc::new(properties.last().unwrap().defense), Acc::update)
|
||||
.count
|
||||
}
|
||||
}
|
||||
struct Solution {}
|
||||
|
||||
fn main() {
|
||||
println!("Hello World!");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_example() {
|
||||
assert_eq!(
|
||||
Solution::number_of_weak_characters(vec![vec![5, 5], vec![6, 3], vec![3, 6]]),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_another_example() {
|
||||
assert_eq!(
|
||||
Solution::number_of_weak_characters(vec![vec![2, 2], vec![3, 3]]),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_another_another_example() {
|
||||
assert_eq!(
|
||||
Solution::number_of_weak_characters(vec![vec![1, 5], vec![10, 4], vec![4, 3]]),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bigger_example() {
|
||||
assert_eq!(
|
||||
Solution::number_of_weak_characters(vec![
|
||||
vec![1, 5],
|
||||
vec![10, 4],
|
||||
vec![4, 3],
|
||||
vec![2, 6],
|
||||
vec![1, 1],
|
||||
vec![10, 6]
|
||||
]),
|
||||
3
|
||||
);
|
||||
}
|
||||
}
|
78
rs/time-needed-to-inform-all-employees.rs
Normal file
78
rs/time-needed-to-inform-all-employees.rs
Normal file
|
@ -0,0 +1,78 @@
|
|||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
|
||||
struct Solution {}
|
||||
impl Solution {
|
||||
fn from_managers(managers: &[i32]) -> HashMap<usize, HashSet<usize>> {
|
||||
let mut mapping = HashMap::new();
|
||||
|
||||
for (i, manager) in managers
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, &manager)| manager != -1)
|
||||
{
|
||||
mapping
|
||||
.entry(*manager as usize)
|
||||
.or_insert_with(HashSet::new)
|
||||
.insert(i);
|
||||
}
|
||||
|
||||
mapping
|
||||
}
|
||||
|
||||
pub fn num_of_minutes(_n: i32, head_id: i32, manager: Vec<i32>, inform_time: Vec<i32>) -> i32 {
|
||||
let manager_mapping = Solution::from_managers(&manager);
|
||||
|
||||
let mut q = VecDeque::new();
|
||||
q.push_back((head_id as usize, 0));
|
||||
|
||||
let mut minutes = -1;
|
||||
while let Some((manager, t)) = q.pop_front() {
|
||||
minutes = std::cmp::max(minutes, t);
|
||||
|
||||
for employee in manager_mapping.get(&manager).unwrap_or(&HashSet::new()) {
|
||||
q.push_back((*employee, t + inform_time[manager]));
|
||||
}
|
||||
}
|
||||
minutes
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// Input: n = 1, headID = 0, manager = [-1], informTime = [0]
|
||||
// Output: 0
|
||||
// Explanation: The head of the company is the only employee in the company.
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(Solution::num_of_minutes(1, 0, vec![-1], vec![0]), 0);
|
||||
}
|
||||
|
||||
// Input: n = 6, headID = 2, manager = [2,2,-1,2,2,2], informTime = [0,0,1,0,0,0]
|
||||
// Output: 1
|
||||
// Explanation: The head of the company with id = 2 is the direct manager of all the employees in the company and needs 1 minute to inform them all.
|
||||
// The tree structure of the employees in the company is shown.
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert_eq!(
|
||||
Solution::num_of_minutes(6, 2, vec![2, 2, -1, 2, 2, 2], vec![0, 0, 1, 0, 0, 0]),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regression_1() {
|
||||
assert_eq!(
|
||||
Solution::num_of_minutes(
|
||||
15,
|
||||
0,
|
||||
vec![-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6],
|
||||
vec![1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
),
|
||||
3
|
||||
);
|
||||
}
|
||||
}
|
56
rs/validate-stack-sequences.rs
Normal file
56
rs/validate-stack-sequences.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
struct Solution {}
|
||||
impl Solution {
|
||||
pub fn validate_stack_sequences(pushed: Vec<i32>, popped: Vec<i32>) -> bool {
|
||||
let mut stack: Vec<i32> = vec![];
|
||||
|
||||
let mut i = 0;
|
||||
let mut j = 0;
|
||||
|
||||
loop {
|
||||
// If the top is to be popped, pop it
|
||||
if let Some(&top) = stack.last() {
|
||||
if j < popped.len() && top == popped[j] {
|
||||
stack.pop();
|
||||
j += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If I have an element that can be pushed, push it
|
||||
if i < pushed.len() {
|
||||
stack.push(pushed[i]);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If I can't pop nor push, it's done or screwed up
|
||||
break;
|
||||
}
|
||||
|
||||
// If it's correct simulation, stack must be empty
|
||||
stack.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn success() {
|
||||
assert!(Solution::validate_stack_sequences(
|
||||
vec![1, 2, 3, 4, 5],
|
||||
vec![4, 5, 3, 2, 1]
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fail() {
|
||||
assert!(!Solution::validate_stack_sequences(
|
||||
vec![1, 2, 3, 4, 5],
|
||||
vec![4, 3, 5, 1, 2]
|
||||
));
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue