#include <stdbool.h>
#include <stdlib.h>
static int cmpInt(const void *a, const void *b) {
return (*(const int *)a > *(const int *)b) - (*(const int *)a < *(const int *)b);
}
bool isNStraightHand(int *hand, int handSize, int groupSize) {
if (handSize % groupSize != 0)
return false;
// C has no ordered map: sort, then collapse into distinct values + counts
qsort(hand, handSize, sizeof(int), cmpInt);
int *vals = malloc(handSize * sizeof(int));
int *cnt = malloc(handSize * sizeof(int));
int m = 0;
for (int i = 0; i < handSize; i++) {
if (m > 0 && vals[m - 1] == hand[i]) {
cnt[m - 1]++;
} else {
vals[m] = hand[i];
cnt[m++] = 1;
}
}
bool ok = true;
for (int i = 0; i < m && ok; i++) {
int c = cnt[i];
if (c == 0)
continue; // already used up by earlier groups
for (int j = 0; j < groupSize; j++) {
// missing value or too few copies: group can't be built
if (i + j >= m || vals[i + j] != vals[i] + j || cnt[i + j] < c) {
ok = false;
break;
}
cnt[i + j] -= c;
}
}
free(vals);
free(cnt);
return ok;
}
#include <map>
#include <vector>
using namespace std;
class Solution {
public:
bool isNStraightHand(vector<int> &hand, int groupSize) {
if (hand.size() % groupSize != 0)
return false;
map<int, int> count;
for (int c : hand)
count[c]++;
while (!count.empty()) {
int start = count.begin()->first; // smallest remaining card
for (int v = start; v < start + groupSize; v++) {
auto it = count.find(v);
if (it == count.end())
return false; // missing value, group can't be built
if (--it->second == 0)
count.erase(it); // drop values that are used up
}
}
return true;
}
};
package greedy
import "sort"
func isNStraightHand(hand []int, groupSize int) bool {
if len(hand)%groupSize != 0 {
return false
}
count := make(map[int]int)
for _, c := range hand {
count[c]++
}
// ascending, so each value is the smallest remaining card when reached
keys := make([]int, 0, len(count))
for k := range count {
keys = append(keys, k)
}
sort.Ints(keys)
for _, start := range keys {
c := count[start]
if c == 0 {
continue // already used up by earlier groups
}
for v := start; v < start+groupSize; v++ {
if count[v] < c {
return false // missing value, group can't be built
}
count[v] -= c
}
}
return true
}
import java.util.Map;
import java.util.TreeMap;
class Solution {
public boolean isNStraightHand(int[] hand, int groupSize) {
if (hand.length % groupSize != 0)
return false;
TreeMap<Integer, Integer> count = new TreeMap<>();
for (int c : hand)
count.merge(c, 1, Integer::sum);
while (!count.isEmpty()) {
int start = count.firstKey(); // smallest remaining card
for (int v = start; v < start + groupSize; v++) {
Integer left = count.get(v);
if (left == null)
return false; // missing value, group can't be built
if (left == 1)
count.remove(v); // drop values that are used up
else
count.put(v, left - 1);
}
}
return true;
}
}
/**
* @param {number[]} hand
* @param {number} groupSize
* @return {boolean}
*/
var isNStraightHand = function (hand, groupSize) {
if (hand.length % groupSize !== 0) return false;
const count = new Map();
for (const c of hand) count.set(c, (count.get(c) ?? 0) + 1);
// ascending, so each value is the smallest remaining card when reached
const keys = [...count.keys()].sort((a, b) => a - b);
for (const start of keys) {
const c = count.get(start);
if (c === 0) continue; // already used up by earlier groups
for (let v = start; v < start + groupSize; v++) {
if ((count.get(v) ?? 0) < c) return false; // missing value, group can't be built
count.set(v, count.get(v) - c);
}
}
return true;
};
from collections import Counter
from typing import List
class Solution:
def isNStraightHand(self, hand: List[int], groupSize: int) -> bool:
if len(hand) % groupSize != 0:
return False
count = Counter(hand)
# ascending, so each value is the smallest remaining card when reached
for start in sorted(count):
c = count[start]
if c == 0:
continue # already used up by earlier groups
for v in range(start, start + groupSize):
if count.get(v, 0) < c:
return False # missing value, group can't be built
count[v] -= c
return True
use std::collections::BTreeMap;
impl Solution {
pub fn is_n_straight_hand(hand: Vec<i32>, group_size: i32) -> bool {
if hand.len() % group_size as usize != 0 {
return false;
}
let mut count = BTreeMap::new();
for c in hand {
*count.entry(c).or_insert(0) += 1;
}
while let Some((&start, _)) = count.first_key_value() {
// start is the smallest remaining card
for v in start..start + group_size {
match count.get_mut(&v) {
None => return false, // missing value, group can't be built
Some(1) => {
count.remove(&v); // drop values that are used up
}
Some(n) => *n -= 1,
}
}
}
true
}
}