LeetCode914:卡牌分组

这是一篇关于LeetCode914题目的解析文章,讨论如何根据整数卡牌找到可行的分组数字。文章通过示例详细解释了不同情况下的解题思路,并分享了一种有效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一副牌,每张牌上都写着一个整数。

此时,你需要选定一个数字 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. 1 <= deck.length <= 10000
  2. 0 <= deck[i] < 10000

解析:

   该题目需要计算出每个数字的数目,然后求数目的公约数,如果公约数不存在,则返回false,否则返回true。

该题目,做题时考虑成了用数目最小值作为公约数,因此出现错误。

代码:

bool hasGroupsSizeX(vector<int>& deck) 
{
	map<int, int>mapDeck;
	int size = deck.size();
	for (int i = 0; i < size; i++)//用map计算每个数字的数目
	{
		mapDeck[deck[i]]++;
	}
	int secondMinOfMapDeck = size;
	//找到数目的最小值
	for (map<int, int>::iterator iter = mapDeck.begin(); iter != mapDeck.end(); iter++)
	{
		if (iter->second < secondMinOfMapDeck)
			secondMinOfMapDeck = iter->second;
	}
	
	if (secondMinOfMapDeck < 2)
		return false;
	//找公约数
	for (int i = 2; i <= secondMinOfMapDeck; i++)
	{
		map<int, int>::iterator iter = mapDeck.begin();
		for (; iter != mapDeck.end(); iter++)
		{
			if (iter->second%i != 0)
				break;
		}
		if (iter == mapDeck.end())
		{
			secondMinOfMapDeck = i;
			break;
		}
	}
	//判断是否是公约数,不是则返回false
	for (map<int, int>::iterator iter = mapDeck.begin(); iter != mapDeck.end(); iter++)
	{
		if (iter->second%secondMinOfMapDeck != 0)
			return false;
	}
	return true;
}

他山之石:

bool hasGroupsSizeX(vector<int>& deck) 
{
        unordered_map<int, int> m;
        int Min = INT_MAX;
        for(int i = 0; i < deck.size(); i++){
            m[deck[i]]++;
        }
        for(auto item: m){//找最小值
            Min = min(Min, item.second);
        }
        for(int i = 2; i <= Min; i++){
            if(Min % i) continue;//有利于减少计算量
            bool flag = true;//判断是否整除
            for(auto item:m){
                if(item.second % i){
                    flag = false;
                    break;
                }
            }
            if(flag)
                return true;
        }
        return false;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值