Skip to content

Commit

Permalink
Add problem 2025: Maximum Number of Ways to Partition an Array
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Aug 21, 2024
1 parent 75ea74a commit a97d9c3
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,7 @@ pub mod problem_2018_check_if_word_can_be_placed_in_crossword;
pub mod problem_2022_convert_1d_array_into_2d_array;
pub mod problem_2023_number_of_pairs_of_strings_with_concatenation_equal_to_target;
pub mod problem_2024_maximize_the_confusion_of_an_exam;
pub mod problem_2025_maximum_number_of_ways_to_partition_an_array;
pub mod problem_2027_minimum_moves_to_convert_string;
pub mod problem_2028_find_missing_observations;
pub mod problem_2029_stone_game_ix;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
pub mod prefix_sum;

pub trait Solution {
fn ways_to_partition(nums: Vec<i32>, k: i32) -> i32;
}

#[cfg(test)]
mod tests {
use super::Solution;

pub fn run<S: Solution>() {
let test_cases = [
((&[2, -1, 2] as &[_], 3), 1),
((&[0, 0, 0], 1), 2),
((&[22, 4, -25, -20, -15, 15, -16, 7, 19, -10, 0, -13, -14], -33), 4),
(
(
&[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
],
0,
),
33,
),
(
(
&[
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, 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, 0, 0, 0, 99, 0, 0, 0,
0, -99, 0,
],
0,
),
60,
),
];

for ((nums, k), expected) in test_cases {
assert_eq!(S::ways_to_partition(nums.to_vec(), k), expected);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::collections::hash_map::{Entry, OccupiedEntry};
use std::collections::HashMap;

impl Solution {
fn unwrap_occupied(entry: Entry<i32, u32>) -> OccupiedEntry<i32, u32> {
match entry {
Entry::Occupied(entry) => entry,
Entry::Vacant(_) => unreachable!(),
}
}

pub fn ways_to_partition(nums: Vec<i32>, k: i32) -> i32 {
let mut right_counts = HashMap::new();
let mut sum = 0;

for &num in &nums {
sum += num;

match right_counts.entry(sum) {
Entry::Occupied(entry) => *entry.into_mut() += 1,
Entry::Vacant(entry) => {
entry.insert(1);
}
}
}

let mut result = if sum % 2 == 0 {
right_counts.get(&(sum / 2)).copied().unwrap_or(0) - u32::from(sum == 0)
} else {
0
};

let mut left_counts = HashMap::new();
let mut left_sum = 0;

for &num in &nums {
left_sum += num;

let right_count = Self::unwrap_occupied(right_counts.entry(left_sum));

if *right_count.get() == 1 {
right_count.remove();
} else {
*right_count.into_mut() -= 1;
}

let diff = k - num;
let new_sum = sum + diff;

if new_sum % 2 == 0 {
let left_half = new_sum / 2;
let right_half = left_half - diff;
let mut score = u32::from(left_sum == right_half);

if let Some(&left_count) = left_counts.get(&left_half) {
score += left_count;
}

if let Some(&right_count) = right_counts.get(&right_half) {
score += right_count;
}

result = result.max(score - u32::from(new_sum == 0));
}

match left_counts.entry(left_sum) {
Entry::Occupied(entry) => *entry.into_mut() += 1,
Entry::Vacant(entry) => {
entry.insert(1);
}
}
}

result as _
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn ways_to_partition(nums: Vec<i32>, k: i32) -> i32 {
Self::ways_to_partition(nums, k)
}
}

#[cfg(test)]
mod tests {
use std::collections::HashMap;

#[test]
fn test_unwrap_occupied_success() {
super::Solution::unwrap_occupied(HashMap::from([(2, 3)]).entry(2));
}

#[test]
#[should_panic(expected = "internal error: entered unreachable code")]
fn test_unwrap_occupied_failure() {
super::Solution::unwrap_occupied(HashMap::from([(2, 5)]).entry(5));
}

#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}

0 comments on commit a97d9c3

Please sign in to comment.