题目链接:https://leetcode.cn/problems/hand-of-straights/
题目大意:给出一数列,求是否能刚好将它们分成若干组,每组的元素数量为groupSize
,并且元素连续。
思路:因为题目的限制很死,如果能够分那么分的结果一定是确定的。那么就可以贪心做。
先排序,并记录每种元素出现的次数,用哈希表cnt
来记。然后从小到大遍历,每轮从【残存次数大于0的最小的数】开始(可以用一个vector
来存这些数字,每个只存一次,起到一个set
一样的效果),然后往后groupSize
的数的残存次数都-1
。如果中间任何一个地方出问题都会不合法,直接返回false
。
做完一下就通过了,但时间不是很理想。于是改了一下,每轮找【残存次数大于0的最小的数】的下标可以复用,直接从上一轮的继承就行了。结果果然快了不少。
完整代码
cpp
class Solution {
public:
bool isNStraightHand(vector<int>& hand, int groupSize) {
int n = hand.size();
if (n % groupSize)
return false;
sort(hand.begin(), hand.end());
vector<int> nums;
unordered_map<int, int> cnt;
for (auto x : hand) {
cnt[x]++;
if (nums.size() == 0 || nums.back() != x)
nums.emplace_back(x);
}
int lpn = n / groupSize;
int idx = 0;
for (int k = 0; k < lpn; k++) {
while (cnt[nums[idx]] == 0)
idx++;
int num = nums[idx];
if (cnt[num]) {
cnt[num]--;
for (int j = num+1; j < num + groupSize; j++) {
if (cnt[j] == 0)
return false;
else
cnt[j]--;
}
}
}
return true;
}
};