Java面试算法题:判断手牌是否为仅含一对+若干三同张的完整手牌
简化版麻将完整手牌判断算法解法
题目描述
你正在开发一款迷你游戏,决定制作简化版麻将游戏。该变体中,玩家拥有标记为0-9的牌,牌可组成同数字的对子或三同张。“完整手牌”定义为:所有牌可分组为任意数量(0个或多个)的三同张,且恰好有一个对子,每张牌仅属于一个组(对子或三同张)。编写函数接收表示玩家手牌的无序字符串(仅含0-9字符),若手牌完整返回“COMPLETE”,否则返回“NOT COMPLETE”。注意:同数字牌可同时存在对子和三同张;仅含一个对子(如99)的手牌有效。
示例
返回“COMPLETE”的有效手牌:
33344466:可分为3的三同张、4的三同张和6的对子55555555:可分为两个5的三同张和一个5的对子22:仅含一个2的对子(无需三同张)
返回“NOT COMPLETE”的无效手牌:
1357:无法组成对子或三同张335577:有三个对子,不符合“恰好一个对子”的要求666888:仅有两个三同张,没有对子
解法思路
- 统计牌面次数:用数组统计0-9每个数字的出现次数(因数字范围固定,数组比HashMap更高效)。
- 尝试对子候选:遍历每个数字,假设该数字作为唯一对子(将其出现次数减2),然后检查剩余所有数字的次数是否都能被3整除——剩余牌必须全部分解为三同张。
- 边界处理:
- 手牌长度小于2直接返回无效(至少需要一个对子)。
- 数字出现次数不足2时,跳过该候选。
- 减2后次数为负的候选直接排除。
- 结果判定:只要存在任意一个符合条件的对子候选,手牌即为完整;否则判定为不完整。
Java 代码实现
public class MahjongHandChecker { public static String checkCompleteHand(String hand) { // 统计0-9每个数字的出现次数 int[] count = new int[10]; for (char c : hand.toCharArray()) { int num = c - '0'; count[num]++; } // 遍历每个数字,尝试作为唯一对子 for (int i = 0; i < 10; i++) { if (count[i] >= 2) { count[i] -= 2; boolean isValid = true; // 验证剩余牌是否都能组成三同张 for (int cnt : count) { if (cnt % 3 != 0) { isValid = false; break; } } if (isValid) { return "COMPLETE"; } // 恢复次数,继续尝试下一个候选 count[i] += 2; } } return "NOT COMPLETE"; } // 测试用例 public static void main(String[] args) { System.out.println(checkCompleteHand("33344466")); // COMPLETE System.out.println(checkCompleteHand("55555555")); // COMPLETE System.out.println(checkCompleteHand("22")); // COMPLETE System.out.println(checkCompleteHand("1357")); // NOT COMPLETE System.out.println(checkCompleteHand("335577")); // NOT COMPLETE System.out.println(checkCompleteHand("666888")); // NOT COMPLETE } }
内容的提问来源于stack exchange,提问作者Pinki Sharma
相关产品推荐
相关产品推荐

