leetcode:那些年我遇到过的编程题013:卡牌分组
分析题意,是让我们判断数组是否能被分成多个小数组,每个小数组元素大于等于2,且元素数目相同,每个元素值相同。
首先想到了使用map,储存每一个卡牌的值还有它的数目,最后选出数目最少的卡牌,确定每个分组元素的最大值。然后遍历[2,max],判断是否存在一个元素数能被所有元素的数目整除。
class Solution {
public boolean hasGroupsSizeX(int[] deck) {
Map<Integer,Integer> list = new HashMap<Integer,Integer>();
for(int i = 0 ; i < deck.length; i++){
if(!list.containsKey(deck[i])){
list.put(deck[i],1);
}else{
list.put(deck[i],list.get(deck[i])+1);
}
}
int min = list.get(deck[0]);
for(int substance : list.keySet()){
if(min > list.get(substance)){
min = list.get(substance);
}
}
a: for(int i = 2; i <= min;i++){
for(int substance : list.keySet()){
if(list.get(substance)%i!=0){
continue a;
}
}
return true;
}
return false;
}
}
唉,今天又是低效率的一天。这道题主要学了,map的几种遍历方法,如:
Map<Integer,Integer> list = new HashMap<Integer,Integer>();
for(list.Entry<Integer,Integer> entry : list.entrySet()){}//遍历元素对
for(int key: list.keySet()){} //遍历key值
for(int value: list.values()){} //遍历value值
下来去评论区看看别人的好方法了
class Solution {
public boolean hasGroupsSizeX(int[] deck) {
// 计数
int[] counter = new int[10000];
for (int num: deck) {
counter[num]++;
}
// 求gcd
int x = 0;
for(int cnt: counter) {
if (cnt > 0) {
x = gcd(x, cnt);
if (x == 1) {
return false;
}
}
}
return x >= 2;
}
// 辗转相除法
private int gcd (int a, int b) {
return b == 0? a: gcd(b, a % b);
}
}
思路稍微绕了一点弯,统计完直接求所有元素数目的公约数即可,如果最后大于1返回true,等于1返回false。