n a deck of cards, each card has an integer written on it.
Return true if and only if you can choose X >= 2 such that it is possible to split the entire deck into 1 or more groups of cards, where:
Each group has exactly X cards.
All the cards in each group have the same integer.
Example 1:
Input: [1,2,3,4,4,3,2,1]
Output: true
Explanation: Possible partition [1,1],[2,2],[3,3],[4,4]
Example 2:
Input: [1,1,1,2,2,2,3,3]
Output: false
Explanation: No possible partition.
Example 3:
Input: [1]
Output: false
Explanation: No possible partition.
Example 4:
Input: [1,1]
Output: true
Explanation: Possible partition [1,1]
Example 5:
Input: [1,1,2,2,2,2]
Output: true
Explanation: Possible partition [1,1],[2,2],[2,2]
Note:
1 <= deck.length <= 10000
0 <= deck[i] < 10000
分析:本题的意思是判断给出数组中出现的数字出现的次数,能不能够被分割成
1.每一部分都大于2的
2.每一部分的数都相同的
满足两个条件。
可以想到的是,可以使用unordered_map或者map来统计数字出现的频率,然后判断。
但是一开始没想太清楚,没能想到是需要求所有数字出现次数的最大公约数。
而且复习了一下最大公约数GCD
bool hasGroupsSizeX(vector<int>& deck) {
unordered_map<int,int>m;
for(int i=0;i<deck.size();i++)
m[deck[i]]++;
int res = 0;
for(auto i :m)res = gcd(i.second,res);
return res>1;
}
int gcd(int a,int b){
if(a<=0&&b<=0)return -1;
if(a<=0)return b;
if(b<=0)return a;
if(a>b)return gcd(a-b,b);
else if(a<b)return gcd(a,b-a);
return a;
}
这里使用的是 更相减损法
int gcd(int a,int b){
if(a<=0||b<=0)return -1;
if(a>b)return gcd(a-b,b);
if(a<b)return gcd(a,b-a);
return a;
}
还有辗转相除法
int gcd(int a,int b){
if(a==0)return b;
return gcd(b%a,a);
}