Alice has a hand of cards, given as an array of integers.

Now she wants to rearrange the cards into groups so that each group is size W, and consists of W consecutive cards.

Return true if and only if she can.

Example 1:

Input: hand = [1,2,3,6,2,3,4,7,8], W = 3
Output: true
Explanation: Alice's hand can be rearranged as [1,2,3],[2,3,4],[6,7,8]

Example 2:

Input: hand = [1,2,3,4,5], W = 4
Output: false
Explanation: Alice's hand can't be rearranged into groups of 4 

Note:

  1. 1 <= hand.length <= 10000
  2. 0 <= hand[i] <= 10^9
  3. 1 <= W <= hand.length

这道题说是我们在打扑克牌,是否能将手里的牌都以顺子的形式出完。在打拐3挖坑或者斗地主的时候,顺子牌在后期的威力是蛮大的,某些人手里憋了一把牌,结果到后期找个机会上手了之后,直接一把甩完,看的手中只有一把单牌的博主是目瞪口呆。其实到了后期,大家手中都没啥牌了的时候,就算是很小的连牌,也不一定能要得起,而划单是最没前途的出法,所以要尽量将手中的牌都组成顺子丢出去。这里给了一个W,规定了顺子的最小长度,那么我们就拿例子1来模拟下打牌吧,首先摸到了牌之后,肯定要先整牌,按从小到大的顺序排列,这里就不考虑啥3最大,4最小啥的,就统一按原始数字排列吧:

1 2 2 3 3 4 6 7 8

好,下面要来组顺子,既然这里是3张可连,那么从最小的开始连呗。其实这道题还是简化了许多,真正打牌的时候,即便是3张起连,那么连4张5张都是可以的,可以这里限定了只能连W张,就使得题目变简单了。我们用贪婪算法就可以了,首先从1开始,那么一定得有2和3,才能起连,若少了任何一个,都可以直接返回false,好那么取出这三张后,手里还有:

2 3 4 6 7 8

那么从当前手里的最小的牌2开始起连,那么手里必须要有3和4,若少了任何一个,都可以直接返回 false,好那么取出这三张后,手里还有:

6 7 8

从当前手里的最小的牌6开始起连,那么手里必须要有7和8,若少了任何一个,都可以直接返回 false,好那么取出这三张后,手里没牌了,我们成功的连完了所有的牌。分析这个过程,不难发现,由于牌可以重复,所以要统计每张牌出现的次数,同时还要给牌按大小排序,用 TreeMap 来建立牌的大小和其出现次数之间的映射就最好不过了,利用了其可以按 key 值排序的特点。首先遍历手中牌,建立映射。然后开始 while 循环,条件是 TreeMap 不为空,然后去除最小的那张牌,然后遍历能组成顺子的W张牌,若没有直接返回 true,有的话,则映射值自减1,若映射值为0了,则从 TreeMap 中移除该映射对儿即可,while 循环退出后返回 true,参见代码如下:

解法一:

class Solution {
public:
bool isNStraightHand(vector<int>& hand, int W) {
map<int, int> m;
for (int i : hand) ++m[i];
while (!m.empty()) {
int start = m.begin()->first;
for (int i = ; i < W; ++i) {
if (!m.count(start + i)) return false;
if (--m[start + i] == ) m.erase(start + i);
}
}
return true;
}
};

我们也可以不对 TreeMap 进行删除操作,而是直接修改其映射值,在建立好映射对儿之后,不用 while 循环,而是遍历所有的映射对儿,若某个映射值为0了,直接跳过。然后还是遍历能组成顺子的W张牌,若某张牌出现的次数小于顺子起始位置的牌的个数,则直接返回 false,因为肯定会有起始牌剩余,无法全组成顺子,这样还避免了上面解法中一张一张减的操作,提高了运算效率。然后映射值减去起始牌的个数,最后 for 循环退出后,返回 true,参见代码如下:

解法二:

class Solution {
public:
bool isNStraightHand(vector<int>& hand, int W) {
map<int, int> m;
for (int i : hand) ++m[i];
for (auto a : m) {
if (a.second == ) continue;
for (int i = a.first; i < a.first + W; ++i) {
if (m[i] < a.second) return false;
m[i] = m[i] - a.second;
}
}
return true;
}
};

Github 同步地址:

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

参考资料:

https://leetcode.com/problems/hand-of-straights/

https://leetcode.com/problems/hand-of-straights/discuss/135700/Short-Java-solution!

https://leetcode.com/problems/hand-of-straights/discuss/135598/C%2B%2BJavaPython-O(MlogM)-Complexity

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Hand of Straights 一手顺子牌的更多相关文章

  1. [Swift]LeetCode846. 一手顺子 | Hand of Straights

    Alice has a hand of cards, given as an array of integers. Now she wants to rearrange the cards into ...

  2. [LeetCode] Shuffle an Array 数组洗牌

    Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] n ...

  3. leetcode(js)算法之914卡牌分组

    给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌. 组内所有的牌上都写着相同的整数. 仅当你可选的 X > ...

  4. Leetcode(870)-优势洗牌

    给定两个大小相等的数组 A 和 B,A 相对于 B 的优势可以用满足 A[i] > B[i] 的索引 i 的数目来描述. 返回 A 的任意排列,使其相对于 B 的优势最大化. 示例 1: 输入: ...

  5. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  6. C#LeetCode刷题-Map

    Map篇 # 题名 刷题 通过率 难度 846 一手顺子   33.7% 中等 855 考场就座   20.8% 中等

  7. 德州扑克AK打法攻略

    AK是所有德扑网游中最受争议的底牌,也是一副令人又爱又恨的底牌.<德州扑克培训大师>根据国内德州扑克网游特性,为大家制作了第一套AK打法攻略,希望所有玩家从今天开始能正确认识AK,发挥AK ...

  8. 我是一只IT小小鸟----读书笔记

    人生如同打牌,能抓到一手好牌固然是运气好,但重要的是,你不能靠运气生活,而要琢磨怎样把手上这把看上去“不怎么样的”牌打好. 要了解一种主流的软件开发与运行平台,熟练掌握一种开发工具,这样就具备了进行开 ...

  9. [Aaronyang] 写给自己的WPF4.5 笔记[2依赖属性]

    人生的意义不在于拿一手好牌,而在于打好一手坏牌 --Aaronyang的博客(www.ayjs.net)-www.8mi.me =============时隔两年后再看WPF========== 因为 ...

随机推荐

  1. PostgreSQL学习笔记(二)-安装pgAdmin

    继上篇安装PostgreSQL后,我们需要安装一个PostgreSQL的图形化管理工具. pgadmin管理工具 创建Python的虚拟环境 cd /root/venv python -m venv ...

  2. L2-010 排座位 (25 分) (最短路)

    链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805066135879680 题目: 布置宴席最微妙的事情,就是给前 ...

  3. Mac下的unity兼容问题,打开项目提示错误:!GetPersistentManager().IsStreamLoaded(assetPath)

    安装unity成功之后,打开unity提示如下 那么打开的unity项目很有可能出现找不到资源的错误. 在检查一下你的Mac宗卷格式,如果是APFS格式的话,基本都会不兼容低版本的32位unity应用 ...

  4. css制作小标志

    空心箭头:示例图片 <b class="bottom"><i class="bottom-arrow1"></i><i ...

  5. 洛谷 P2678 & [NOIP2015提高组] 跳石头

    题目链接 https://www.luogu.org/problemnew/show/P2678 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布 ...

  6. The type javax.servlet.http.HttpServletResponse cannot be resolved. It is indirectly referenced from required .class files

    The type javax.servlet.http.HttpServletResponse cannot be resolved. It is indirectly referenced from ...

  7. ubuntu apt不使用代理

    常见的问题是apt使用代理. 不过今天遇到的情况是,桌面进不去,只能tty:在tty界面下,发现1080端口上开着代理,/etc/environment和~/.bashrc中都确保注释掉了http_p ...

  8. DevExpress控件库 开发使用经验总结3 制作项目安装包

    2015-01-27 使用DevExpress控件包开发C/S项目完成后,部署前需要制作本地安装包.本文还是使用“SetupFactory”安装工厂来制作安装包.在以前的系列文章中详细介绍过该工具的使 ...

  9. Docker 学习7 Dockerfile详解

    一.镜像的生成途径 1.使用当前进程替换上一个进程 exec 2.生成方式 3.dockerfile制作镜像要求 a.要有专有的工作目录. b.要有专门的制作文件,文件名首字母大写 c.如果要打包很多 ...

  10. UOJ#41. 【清华集训2014】矩阵变换 构造

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ41.html 题解 首先写个乱搞: 一开始每一行都选择第一个非0元素,然后,我们对这个方案不断做更新,直到 ...