(Good topic)卡牌分组(3.27leetcode每日打卡)

给定一副牌,每张牌上都写着一个整数。
此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组:

 每组都有 X 张牌。
 组内所有的牌上都写着相同的整数。

仅当你可选的 X >= 2 时返回 true。
 
示例 1:
输入:[1,2,3,4,4,3,2,1]
输出:true
解释:可行的分组是 [1,1],[2,2],[3,3],[4,4]

示例 2:
输入:[1,1,1,2,2,2,3,3]
输出:false
解释:没有满足要求的分组。

示例 3:
输入:[1]
输出:false
解释:没有满足要求的分组。

示例 4:
输入:[1,1]
输出:true
解释:可行的分组是 [1,1]

示例 5:
输入:[1,1,2,2,2,2]
输出:true
解释:可行的分组是 [1,1],[2,2],[2,2]
 
提示:

 1 <= deck.length <= 10000
 0 <= deck[i] < 10000
 
思路:1.如果规模小于等于2直接返回false
2.如果计数中有一个数字等于1,则也不能完成分组,返回false
3.再看示例5,四个二被分成了两组,就知道应该要求数组中数字个数的最大公约数,根据最大公约数进行分组,这里利用递归求最大公约数。
 1 int gcd(int a, int b)
 2 {
 3     if(b == 0)
 4     {
 5         return a;
 6     }
 7     return gcd(b, a % b);
 8 }
 9 
10 bool hasGroupsSizeX(int* deck, int deckSize)
11 {
12     if(deckSize < 2)
13     {
14         return false;
15     }
16 
17     int *cnt = (int *)malloc(sizeof(int) * 10000);
18     for(int i = 0; i < deckSize; i++)
19     {
20         cnt[i] = 0;
21     }
22     for(int i = 0; i < deckSize; i++)  //计数
23     {
24         cnt[deck[i]]++;
25     } 
26     
27     int x = cnt[deck[0]];
28 
29     for(int i = 0; i < 10000; i++)
30     {
31         if(cnt[i] == 1)  //如果碰到1
32         {
33             return false;
34         }
35 
36         if(cnt[i] > 1)
37         {
38             x = gcd(x, cnt[i]);
39 
40             if(x == 1) //如果公约数出现一就说明没有一个固定的x,也不能分组
41             {
42                 return false;
43             }
44 
45         }
46     }
47     return true;
48 }

 

 

 
 
posted @ 2020-03-27 11:08  Xxaj5  阅读(257)  评论(15编辑  收藏  举报