Alice has a hand
of cards, given as an array of integers.
Now she wants to rearrange the cards into groups so that each group is size W
, and consists of W
consecutive cards.
Return true
if and only if she can.
Example 1:
Input: hand = [1,2,3,6,2,3,4,7,8], W = 3 Output: true Explanation: Alice'shand
can be rearranged as[1,2,3],[2,3,4],[6,7,8]
.
Example 2:
Input: hand = [1,2,3,4,5], W = 4 Output: false Explanation: Alice'shand
can't be rearranged into groups of4
.
Note:
1 <= hand.length <= 10000
0 <= hand[i] <= 10^9
1 <= W <= hand.length
题意:Alice有一些牌,问能否将这些牌分为若干个长度为W的连续段。
方法一:利用了优先队列,每次将队首元素出队后,向后找W-1个连续元素。注意,这里需要判断元素是否相同,使用了一个动态数组,将重复出现的元素记录并再加入队列。具体实现看代码:
class Solution {
public:
bool isNStraightHand(vector<int>& hand, int W) {
if(hand.size()%W!=0)
return 0;
else if(W==1) {
return 1;
}else {
int cnt,k,last;
priority_queue<int,vector<int>,greater<int> >que;
vector<int>vec; //vec记录重复出现的元素
vector<int>vec2; //vec2记录每次的连续元素段
for(int i=0;i<hand.size();i++){
que.push(hand[i]);
}
while(!que.empty()){ //每次循环找w个连续数字
k=1;
cnt=0;
vec.clear();
//vec2.clear();
last=que.top();
//vec2.push_back(que.top());
que.pop();
while(!que.empty()&&k<W){
if(que.top()==last){
vec.push_back(last);
que.pop();
cnt++;
}else{
if(que.top()-last!=1)
return 0;
//vec2.push_back(que.top());
last=que.top();
que.pop();
k++;
}
}
if(k==W){ //找完完整的,再将重复的重新加入
while(cnt>0){
que.push(vec.back());
vec.pop_back();
cnt--;
}
/*
for(int i=0;i<k;i++)
printf("%d ",vec2[i]);
printf("\n");
*/
}
}
if(que.empty()&&k==W)
return 1;
else
return 0;
}
}
};
方法二:C++中map是自动排序的,用map保存每张牌出现的次数。从小到大遍历,找当前元素后W-1个连续元素即可。
class Solution {
public:
bool isNStraightHand(vector<int>& hand, int W) {
map<int,int>mp;
//map是按照关键字进行自动排序
for(int num : hand){
mp[num]++;
}
for(auto t : mp){
//以键值对的形式从mp中取数据
int key=t.first;
int value=t.second;
if(value>0){
for(int i=1;i<W;i++){
if(!mp.count(key+i))
return 0;
else{
mp[key+i]-=value;
if(mp[key]+i<0)
return false;
}
}
}
}
return mp.size()==0?0:1;
}
};