Skip to content

45 扑克牌顺子

题目描述

LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!0表示大王或小王。现在,给你5张牌,判断是否是顺子。

解题思路

核心思想:排序后判断。

关键步骤

  1. 统计大王小王的数量
  2. 排序
  3. 计算相邻数字的差距,用大王小王填补
  4. 判断是否有重复的数字(大王小王除外)

时间复杂度: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个大王小王
最近更新

基于 MIT 许可发布