45 扑克牌顺子
题目描述
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!0表示大王或小王。现在,给你5张牌,判断是否是顺子。
解题思路
核心思想:排序后判断。
关键步骤:
- 统计大王小王的数量
- 排序
- 计算相邻数字的差距,用大王小王填补
- 判断是否有重复的数字(大王小王除外)
时间复杂度:O(n log n) 空间复杂度:O(1)
Python 实现
python
def is_continuous(nums):
"""
判断扑克牌是否是顺子
Args:
nums: 5张牌的数组,0表示大小王
Returns:
bool: 是否是顺子
"""
if not nums or len(nums) != 5:
return False
# 统计大王小王的数量
num_of_zero = nums.count(0)
# 排序
nums.sort()
# 计算相邻数字的差距
gap = 0
for i in range(num_of_zero, len(nums) - 1):
# 有对子,不是顺子
if nums[i] == nums[i + 1]:
return False
gap += nums[i + 1] - nums[i] - 1
# 大王小王可以填补的数字
return gap <= num_of_zero
# 测试代码
if __name__ == "__main__":
test_cases = [
[0, 1, 2, 3, 4], # True (0可以当5)
[1, 2, 3, 4, 5], # True
[0, 0, 1, 2, 3], # True
[0, 3, 5, 7, 9], # False
[1, 2, 3, 4, 5], # True
[0, 1, 3, 4, 5], # True
]
for nums in test_cases:
print(f"{nums} {'是' if is_continuous(nums[:]) else '不是'}顺子")
# 输出:
# [0, 1, 2, 3, 4] 是顺子
# [1, 2, 3, 4, 5] 是顺子
# [0, 0, 1, 2, 3] 是顺子
# [0, 3, 5, 7, 9] 不是顺子
# [1, 2, 3, 4, 5] 是顺子
# [0, 1, 3, 4, 5] 是顺子图解
示例: [0, 1, 2, 3, 4]
排序: [0, 1, 2, 3, 4]
大王小王数: 1
计算gap:
1到2: gap += 0
2到3: gap += 0
3到4: gap += 0
总gap: 0
gap(0) <= num_of_zero(1) → True
0可以填补空缺(当作5)
---
示例: [0, 1, 3, 4, 5]
排序: [0, 1, 3, 4, 5]
大王小王数: 1
计算gap:
1到3: gap += 1
3到4: gap += 0
4到5: gap += 0
总gap: 1
gap(1) <= num_of_zero(1) → True
0填补2的位置
---
示例: [0, 3, 5, 7, 9]
排序: [0, 3, 5, 7, 9]
大王小王数: 1
计算gap:
3到5: gap += 1
5到7: gap += 1
7到9: gap += 1
总gap: 3
gap(3) > num_of_zero(1) → False
需要填补3个数字,但只有1个大王小王