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. hihocoder 1176

    hihocoder 1176 题意:N,M.分别表示岛屿数量和木桥数量,一笔画 分析:欧拉路问题(给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,该条路称为欧拉路) 欧拉路的条件 一个无向 ...

  2. [Kubernetes]PV,PVC,StorageClass之间的关系详解

    在Kubernetes中,容器化一个应用比较麻烦的地方莫过于对其"状态"的管理,而最常见的"状态",莫过于存储状态. 在[Kubernetes]深入理解Stat ...

  3. JAVA学习笔记(4)—— 排序算法

    排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. 排序算法大体可分为两种: 一种是比较排序,时间复杂度O(nlogn) ...

  4. dotnet core使用开源组件FastHttpApi进行web应用开发(转)

      FastHttpApi相对于asp.net mvc来说有着更轻量和性能上的优势,性能上面就不在这里介绍了(具体可查看 https://github.com/IKende/FastHttpApi). ...

  5. Mysql 反向解析 导致远程访问慢

    在云端部署了mysql后,发现远程连接的响应速度非常慢(3-10s) 但是在本地访问数据库却没有问题 经过一番google这才知道原来mysql默认会进行反向解析,即通过ip地址反向向ISP申请获取域 ...

  6. 十个推荐使用的 Laravel 的辅助函数

    壹. array_dot() array_dot () 辅助函数允许你将多维数组转换为使用点符号的一维数组. $array = [ 'user' => ['username' => 'so ...

  7. 清晰讲解SQL语句中的外连接,通用于Mysql和Oracle,全是干货哦

    直入主题: 我们做一个操作,将员工SCOTT的部门去掉,再次通过内连接查看数据,看看会产生什么现象? 使用内连接,查询数据 问题:找不到SCOTT员工了,只有13条数据,这显然不合理:这就是内连接的缺 ...

  8. 如何在html显示当前时间

    下边那个是一直快速跳转的 <!doctype html>  <html>  <head>  <meta charset="utf-8"&g ...

  9. python中hasattr()、getattr()、setattr()函数的使用

    1. hasattr(object, name) 判断object对象中是否存在name属性,当然对于python的对象而言,属性包含变量和方法:有则返回True,没有则返回False:需要注意的是n ...

  10. 马拉车算法——边界拓展时加限制hdu4513

    #include<bits/stdc++.h> using namespace std; #define maxn 500005 int n,p[maxn],s[maxn],s_new[m ...