在斗地主扑克牌游戏中, 扑克牌由小到大的顺序为:3,4,5,6,7,8,9,10,J,Q,K,A,2,玩家可以出的扑克牌阵型有:单张、对子、顺子、飞机、炸弹等其中顺子的出牌规则为:由 至少 5 张由小到大连续递增 的扑克牌组成,且 不能包含 2 。例如:{3,4,5,6,7}、{3,4,5,6,7,8,9,10,J,Q,K,A}都是有效的顺子;而{J,Q,K,A,2}、 {2,3,4,5,6}、{3,4,5,6}、{3,4,5,6,8}等都不是顺子。给定一个包含13张牌的数组,如果有满足出牌规则的顺子,请输出顺子。如果存在多个顺子,请每行输出一个顺子,且需要按顺子的 第一张牌的大小(必须从小到大) 依次输出。如果没有满足出牌规则的顺子,请 输出 No 。
时间: 2025-03-15 18:15:16 浏览: 63
找到所有符合规则的有效顺子排列
要解决这个问题,可以从以下几个方面入手:
1. 定义顺子
顺子是指一组连续的扑克牌序列。在斗地主游戏中,A 被认为是 1,而不是 14;因此,顺子的最大长度为 K-A (13-1=12)[^1]。
2. 处理大小王
大小王被表示为 0
,它们可以用作任何其他牌来填补缺失的部分。这意味着如果有多个 0
存在,则可以通过这些 0
来补全不完整的顺子[^2]。
3. 算法设计
为了找出所有的有效顺子组合,可以采用以下方法:
- 首先统计输入数组中非零元素的数量以及其范围(最大值与最小值之间的差)。
- 如果存在重复的非零数字,则不可能形成顺子。
- 使用
0
的数量去填充可能存在的间隙。
以下是具体的 Python 实现代码:
def is_straight(hand):
hand.sort() # 对手牌进行排序
zeros = 0
gap = 0
for i in range(len(hand)):
if hand[i] == 0:
zeros += 1 # 统计大小王的数量
elif i > 0 and hand[i] == hand[i - 1]:
return False # 出现重复数字则无法构成顺子
elif i > 0 and hand[i - 1] != 0:
gap += hand[i] - hand[i - 1] - 1 # 计算相邻数字间的差距
return gap <= zeros # 判断是否有足够的大小王填满空缺
# 测试函数
hands = [
[0, 3, 4, 5, 6], # True
[7, 8, 9, 10, 11], # True
[0, 0, 1, 2, 5], # True
[0, 0, 1, 2, 6], # False
]
for h in hands:
result = is_straight(h)
print(f"{h} -> {result}")
上述代码实现了判断单个五张牌是否为顺子的功能。对于更复杂的场景——比如从 13 张牌中提取所有有效的顺子组合,可以扩展此逻辑并枚举所有可能的五个子集。
4. 复杂度分析
该解决方案的时间复杂度主要取决于两部分:一是对每组五张牌执行一次 O(n log n) 排序操作;二是遍历整个列表计算间隔数目,时间复杂度为 O(n),其中 n 是当前手中卡片数。总体上效率较高,适合实际应用需求。
相关推荐


















