最近逛知乎的时候看到了这样一個题目,于是随便搜了一下,这是微软的一道面试题,题目如下:
1. 这个题目要求提供最终代码(C#)
2. 该最终代码必须可以编译,运行,并实现以下的业务功能
3. 限制时间一个小时, 包括阅读文档和提交代码的时间
给定若干张的麻将牌 (假设只有 万 一种类型,没有条和筒)
最终胡牌必须满足以下条件
所囿的牌必须连成顺子或者3张 即:123 或者111
最后还要有一对, 例如 11
//这里是你的代码
返回参数是true 就代表胡牌, false 代表不能胡牌
之前其实恰好有随手寫过这样一个 demo,而且考虑了红中赖子的情况,不过没有给出具体思路,代码也写得很凌乱...详见:
这里按照题目的要求,不考虑红中赖子的因素,简化代碼,另一并给出使用穷举法解题的思路:
3N+2,首先,要明确的是,一副手牌如果胡牌,必定遵循 3N+2 的手牌牌型,即 n(可以为 0)组顺子(暗刻)+ 一对将(掌门)...
首先是外围代碼,我们创建对应的麻将花色枚举类和操作类:
以及开局洗牌,发牌等逻辑:
然后,我们将相同牌放到一起,然后排号顺序:
如果没有牌型没有任何对子,那么肯定无法胡牌,如果包含对子,我们就看剩下的能否全部组成顺子或者暗刻;
上面的代码中有体现出,会不停的尝试多种对子作为掌门的情况,矗到能判定成功胡牌为止!
其中深度复制方法用于让原始数据(引用型)可以重复使用不被影响;
我们看看如何处理 3N 的:
由于会递归调用此方法,只有當以上两种组合完全排除后,剩下的则一定要组成暗刻 check.size() == 3,被整体移除三张;
最后如果所有的牌都被成功移除,满足
表示此手牌不是顺子就是暗刻,成功胡牌,我们看一下处理顺子的具体逻辑
关键逻辑就是判断三张牌是否同花色并且点数连续...
以上就是使用递归法判断麻将手牌是否胡牌的全解,代码写的有点狗屎,有丁点兴趣的童鞋可在 github 上找到,传送门: