In 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. 1 <= deck.length <= 10000
  2. 0 <= deck[i] < 10000

这道题给了一堆牌,问我们能不能将这副牌分成若干堆,每堆均有X个,且每堆的牌数字都相同(这里不考虑花色)。既然要将相同的牌归类,肯定要统计每种牌出现的个数,所以使用一个 HashMap 来建立牌跟其出现次数之间的映射。由于每堆X个,则若果某张牌的个数小于X,则肯定无法分,所以X的范围是可以确定的,为 [2, mn],其中 mn 是数量最少的牌的个数。遍历一遍 HashMap,找出最小的映射值 mn,若 mn 小于2,可以直接返回 false。否则就从2遍历到 mn,依次来检验候选值X。检验的方法是看其他每种牌的个数是否能整除候选值X,不一定非要相等,比如 [1, 1, 2, 2, 2, 2], K=2 时就可以分为三堆 [1, 1], [2, 2], [2, 2],即相同的牌也可以分到其他堆里,所以只要每种牌的个数能整除X即可,一旦有牌数不能整除X了,则当前X一定不行,还得继续检验下一个X值;若所有牌数都能整除X,可以返回 true。循环结束后返回 false,参见代码如下:


解法一:

class Solution {
public:
bool hasGroupsSizeX(vector<int>& deck) {
unordered_map<int, int> cardCnt;
for (int card : deck) ++cardCnt[card];
int mn = INT_MAX;
for (auto &a : cardCnt) mn = min(mn, a.second);
if (mn < 2) return false;
for (int i = 2; i <= mn; ++i) {
bool success = true;
for (auto &a : cardCnt) {
if (a.second % i != 0) {
success = false;
break;
}
}
if (success) return true;
}
return false;
}
};

上面的解法是博主自己的解法,论坛上好多人使用了一个基于最大公约数 Greatest Common Divisor 的解法,写起来很简洁,但需要记住最大公约函数的写法,或者直接使用内置的 gcd 函数(感觉有点耍赖哈~)。其实原理都差不多,这里是找每种牌数之间的最大公约数,只要这个 gcd 是大于1的,就表示可以找到符合题意的X,参见代码如下:


解法二:

class Solution {
public:
bool hasGroupsSizeX(vector<int>& deck) {
unordered_map<int, int> cardCnt;
for (int card : deck) ++cardCnt[card];
int res = 0;
for (auto &a : cardCnt) {
res = gcd(a.second, res);
}
return res > 1;
}
int gcd(int a, int b) {
return a == 0 ? b : gcd(b % a, a);
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/914

参考资料:

https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/

https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/discuss/175845/C%2B%2BJavaPython-Greatest-Common-Divisor

https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/discuss/309992/Java-Easy-to-understand-2-ms-faster-than-98.92-38.5-MB-less-than-99.23

[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)

[LeetCode] 914. X of a Kind in a Deck of Cards 一副牌中的X的更多相关文章

  1. [leetcode]914. X of a Kind in a Deck of Cards (easy)

    原题 题目原意可转换为 两组有大于等于2的公因数 /** * @param {number[]} deck * @return {boolean} */ var hasGroupsSizeX = fu ...

  2. LeetCode.914-一副牌中的X(X of a Kind in a Deck of Cards)

    这是悦乐书的第352次更新,第377篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第214题(顺位题号是914).在一副牌中,每张牌上都写有一个整数. 当且仅当您可以选择 ...

  3. 【Leetcode_easy】914. X of a Kind in a Deck of Cards

    problem 914. X of a Kind in a Deck of Cards 题意:每个数字对应的数目可以均分为多组含有K个相同数目该数字的数组. 思路:使用 map 结构记录数组中每个元素 ...

  4. 【LeetCode】914. X of a Kind in a Deck of Cards 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历 最大公约数 日期 题目地址: https:// ...

  5. 914. X of a Kind in a Deck of Cards

    In a deck of cards, each card has an integer written on it. Return true if and only if you can choos ...

  6. [LeetCode] 105. Construct Binary Tree from Preorder and Inorder Traversal 由先序和中序遍历建立二叉树

    Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  7. 【LeetCode】105. Construct Binary Tree from Preorder and Inorder Traversal 从前序与中序遍历序列构造二叉树(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...

  8. LeetCode - X of a Kind in a Deck of Cards

    In a deck of cards, each card has an integer written on it. Return true if and only if you can choos ...

  9. 【LeetCode每天一题】Search in Rotated Sorted Array(在旋转数组中搜索)

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.(i.e., ...

随机推荐

  1. 聊一下,前后分离后带来的跨域访问和cookie问题

    在谈前后分离前,我们先看看什么是前后一体的.当我们用javaweb开发网站时,最终我们渲染的jsp或者springthymeleaf.我们的页面其实是WEB-INFO或者templates下.当用户请 ...

  2. D3力布图绘制--节点间的多条关系连接线的方法(转)

    在项目中遇到这样的场景,在使用D3.js绘制力布图的过程中,需要在2个节点间绘制多条连接线,找到一个不错的算法,在此分享下. 效果图: HTML中要连接 <!DOCTYPE html> & ...

  3. Nginx反向代理YUM请求

    一.安装配置Nginx服务(Nginx服务器上建议先关闭iptables/firewalld服务,待实验完成后再根据实际情况配置) [root@localhost ~]# yum install ng ...

  4. Neo4j 第十二篇:使用Python驱动访问Neo4j

    neo4j官方驱动支持Python语言,驱动程序主要包含Driver类型和Session类型.Driver对象包含Neo4j数据库的详细信息,包括主机url.安全验证等配置,还管理着连接池(Conne ...

  5. mysql的sql调优: slow_query_log_file

    mysql有一个功能就是可以log下来运行的比较慢的sql语句,默认是没有这个log的,为了开启这个功能,要修改my.cnf或者在mysql启动的时候加入一些参数.如果在my.cnf里面修改,需增加如 ...

  6. Python学习之路 【目录】

           * Python之路[楔子]:PyCharm 专业版安装      * Python之路[第一篇]:Python简介和入门      * Python之路[第二篇]:Python基础(一 ...

  7. 十七:迭代器模式详解(foreach的精髓)

    定义:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 从定义中可以看出,迭代器模式是为了在不暴露该对象内部表示的情况下,提供一种顺序访问聚合对象中元素的方法.这种思想在JA ...

  8. React用脚手架实际开发项目!

    安装脚手架: npm i create-react-app -g 创建项目命令: create-react-app 项目名字 启动命令:yarn start 如果不用脚手架,需要创建一下页面: 再安装 ...

  9. 英语chrismatite黄蜡石chrismatite单词

    黄蜡石chrismatite的原岩均为硅质岩,各种原岩受到构造变动.火山活动.热液作用等影响,产生复杂的物理和化学变化,包括重结晶.热变质等,导致矿物成分及结构构造的变化,后受构造变动的影响,岩石露出 ...

  10. Facebook发布全新JavaScript引擎:Hermes

    摘要: JS引擎开始升级了... 原文:技术栈中的爱马仕?Facebook发布全新JavaScript引擎:Hermes 作者:Carson_Ho Fundebug经授权转载,版权归原作者所有. 前言 ...