pub fn is_n_straight_hand(hand: Vec<i32>, group_size: i32) -> bool {
use std::cmp::Reverse;
use std::collections::BinaryHeap;
use std::collections::HashMap;
if (hand.len() as i32) % group_size != 0 {
// 张数不对
return false;
}
let mut counter = HashMap::new();
let mut pq = BinaryHeap::new();
for card in hand {
*counter.entry(card).or_insert(0) += 1;
pq.push(Reverse(card));
}
while !pq.is_empty() {
let start = pq.pop().unwrap().0;
let entry = counter.entry(start).or_default();
if *entry == 0 {
// 起点已经被消耗了, 重新选一个
continue;
}
*entry -= 1; //消耗一个
for i in 1..group_size {
// 因为连续, 所以可以枚举
let e = counter.entry(start + i).or_default();
if *e == 0 {
// 凑不出连续
return false;
}
*e -= 1;
}
}
true
}
上面用了优先队列, 其实可以不用, 直接排序就可以, 本意都是要一个有序的即可.
pub fn is_n_straight_hand(hand: Vec<i32>, group_size: i32) -> bool {
use std::collections::HashMap;
if (hand.len() as i32) % group_size != 0 {
// 张数不对
return false;
}
let mut hand = hand;
hand.sort();
let mut counter = HashMap::new();
for &card in hand.iter(){
*counter.entry(card).or_insert(0) += 1;
}
for i in 0..hand.len(){
let start = hand[i];
let e= counter.entry(start).or_default();
if *e ==0 {
// 跳过, 下一个
continue;
}
*e -= 1;
for i in 1..group_size{
// 开始假设枚举
let e = counter.entry(start+i).or_default();
if *e == 0{
return false;
}
*e -= 1;
}
}
true
}