问题描述
Alice 手中有一把牌,她想要重新排列这些牌,分成若干组,使每一组的牌数都是
groupSize
,并且由groupSize
张连续的牌组成。给你一个整数数组
hand
其中hand[i]
是写在第i
张牌上的数值。如果她可能重新排列这些牌,返回true
;否则,返回false
。
示例
示例 1:
输入:hand = [1,2,3,6,2,3,4,7,8], groupSize = 3 输出:true 解释:Alice 手中的牌可以被重新排列为[1,2,3],[2,3,4],[6,7,8]。
示例 2:
输入:hand = [1,2,3,4,5], groupSize = 4 输出:false 解释:Alice 手中的牌无法被重新排列成几个大小为 4 的组。提示:
1 <= hand.length <= 10^4
0 <= hand[i] <= 10^9
1 <= groupSize <= hand.length
问题分析:
一眼连续子集问题,并且还给了子集的长度,直接用最基本直接的思路,来解决这种问题。不难知道,如果要找一个连续的子集,肯定用较小的元素来开头。因此我们用一个map来记录元素及其出现次数。遍历完map即可,最后map为空就return true,不然就false
代码如下:
class Solution {
public:
bool isNStraightHand(vector<int>& hand, int groupSize) {
int n = hand.size();
//如果除不尽,就直接false
if(n % groupSize != 0) return false;
else
{
map<int, int> mp;
for(int num : hand)
{
mp[num] ++;
}
//要用这种遍历方式来找最小元素,不然这个案例过不了1,1,2,2,3,3
while(!mp.empty())
{
//开头确定永远是map中最小的元素
int now = mp.begin()->first;
mp[now] --;
//一旦该元素使用殆尽,清除
if(mp[now] == 0)
{
mp.erase(now);
}
//遍历查找当前最小元素后面的连着groupsize个元素在不在map中
for(int i = 1; i < groupSize; i ++)
{
now ++;
if(mp.find(now) != mp.end())
{
mp[now] --;
if(mp[now] == 0)
{
mp.erase(now);
}
}
//如果没有
else
return false;
}
}
}
return true;
}
};