89 lines
2 KiB
Rust
89 lines
2 KiB
Rust
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);
|
|
}
|
|
}
|