给定一副牌,每张牌上都写着一个整数。
此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组:
每组都有 X 张牌。
组内所有的牌上都写着相同的整数。
仅当你可选的 X >= 2 时返回 true。
提示:
1 <= deck.length <= 10000
0 <= deck[i] < 10000
思路:需要新建1个数组,用来存放分组情况,初始值全部为0。先对输入的数组进行遍历来进行对每个元素的统计,将统计结果放到新的数组里,最后只需要遍历新的数组值时,对统计结果求最小公因数,若是存在大于1的公因数,就返回true。
在这里求最小公因数用辗转相除法
代码如下
class Solution {
public:
int max(int x, int y)
{
if (x > y)
return x;
else
return y;
}
int min(int x, int y)
{
if (x > y)
return y;
else
return x;
}
int min_num(int x, int y)
{
int dived_num = max(x, y);
int div_num = min(x, y);
while(dived_num % div_num != 0)
{
int result = dived_num % div_num;
dived_num = div_num;
div_num = result;
}
return div_num;
}
bool hasGroupsSizeX(vector<int>& deck) {
vector<int>count_deck(deck.size(), 0);
int count;
int k = 0;
//对deck中的元素进行数量统计,结果存到count_deck数组中
for (int i = 0; i < deck.size(); i++)
{
count = 1;
if (deck[i] == -1)
continue;
for (int j = i + 1; j < deck.size(); j++)
{
if (deck[i] == deck[j])
{
count++;
deck[j] = -1;
}
}
count_deck[k] = count;
k++;
}
int min = count_deck[0];
//找出数量统计中的最小值
for (int i = 1; i < k; i++)
{
if (min > count_deck[i])
min = count_deck[i];
}
//判断是否可以分组
if (min == 1)
return false;
for (int i = 0; i < k; i++)
{
for (int j = 0; j < k; j++)
{
if (min_num(count_deck[i], count_deck[j]) == 1)
return false;
}
}
return true;
}
};
但是性能比较差
结果
参考答案:
思路一致,但是比我的简洁多了,效率也高
大神的代码:
bool hasGroupsSizeX(vector<int>& deck) {
int counts[10000] = {0};
int g = 0;
for (int d : deck) {
counts[d]++;
}
for (int b : counts){
if(b == 0) continue;
g = gcd(b, g);
if(g == 1) return false;
}
return g >= 2;
}