寻找最大葫芦 | 豆包MarsCode AI刷题

226 阅读4分钟

问题解析

在经典德州扑克的“葫芦”牌型基础上,添加了限制条件:组成“葫芦”的五张牌总和不能超过给定的最大值 max_value。任务是找到一个符合条件的“葫芦”组合,优先比较三张牌(a),然后比较两张牌(b)。如果不存在符合条件的组合,则返回 [0, 0]


解题思路

  1. 统计牌频率

    • 使用 collections.Counter 统计每种牌的频率。

    • 筛选出满足条件的牌值列表:

      • 至少出现 3 次的牌作为“三张”候选。
      • 至少出现 2 次的牌作为“两张”候选。
  2. 枚举所有可能的组合

    • 遍历“三张”候选列表,与“两张”候选列表两两组合,判断是否满足“葫芦”的限制条件。

    • 确保:

      • 三张与两张牌值可以是相同,但需满足总数足够构成“葫芦”(至少 5 张)。
      • 总和不超过 max_value
  3. 比较规则

    • 若多个组合符合条件,则按如下顺序选择最优组合:

      1. 首先比较三张牌值(A=1 为最大,K=13,Q=12,...)。
      2. 若三张牌值相同,再比较两张牌值。
  4. 处理 A 的特殊性

    • 在德州扑克中,A 的牌值为 1,但在比较大小时需视为最大牌值(等效于 14),需在比较时调整。
  5. 输出结果

    • 如果找到符合条件的“葫芦”,输出 [a, b]
    • 如果找不到,输出 [0, 0]

实现代码

以下是完整的 Python 实现:

def solution(n, max_value, array):
    from collections import Counter

    # 统计牌的出现次数
    count = Counter(array)

    # 筛选至少出现 3 次的牌值
    three_count_numbers = [num for num, cnt in count.items() if cnt >= 3]
    # 筛选至少出现 2 次的牌值
    two_count_numbers = [num for num, cnt in count.items() if cnt >= 2]

    # 初始化结果
    max_combination = [0, 0]

    # 枚举所有三张牌和两张牌的组合
    for three_num in three_count_numbers:
        for two_num in two_count_numbers:
            # 如果三张和两张是同一牌值,确保数量足够(至少 5 张)
            if three_num == two_num and count[two_num] < 5:
                continue

            # 计算总和
            total = three_num * 3 + two_num * 2

            # 转换 A 的牌值为 14,用于比较大小
            comp_three_num = 14 if three_num == 1 else three_num
            comp_two_num = 14 if two_num == 1 else two_num

            # 如果总和符合要求,更新最大组合
            if total <= max_value:
                if (comp_three_num, comp_two_num) > tuple(max_combination):
                    max_combination = [comp_three_num, comp_two_num]

    # 将 A 的值从 14 转回 1
    if max_combination[0] == 14:
        max_combination[0] = 1
    if max_combination[1] == 14:
        max_combination[1] = 1

    return max_combination


if __name__ == "__main__":
    # 测试用例
    print(solution(9, 34, [6, 6, 6, 8, 8, 8, 5, 5, 1]) == [8, 5])   # 示例 1
    print(solution(9, 37, [9, 9, 9, 9, 6, 6, 6, 6, 13]) == [6, 9])  # 示例 2
    print(solution(9, 40, [1, 11, 13, 12, 7, 8, 11, 5, 6]) == [0, 0])  # 示例 3

测试样例分析

示例 1

输入

n = 9, max_value = 34, array = [6, 6, 6, 8, 8, 8, 5, 5, 1]

分析

  • 候选“三张”:[6, 8]

  • 候选“两张”:[5, 6, 8]

  • 有效组合:

    • [8, 5]:总和 = 8×3+5×2=348 \times 3 + 5 \times 2 = 34。
    • [6, 8]:总和 = 6×3+8×2=346 \times 3 + 8 \times 2 = 34。
  • 比较三张优先级,8 > 6,选择 [8, 5]

输出

[8, 5]

示例 2

输入

n = 9, max_value = 37, array = [9, 9, 9, 9, 6, 6, 6, 6, 13]

分析

  • 候选“三张”:[9, 6]

  • 候选“两张”:[9, 6]

  • 有效组合:

    • [6, 9]:总和 = 6×3+9×2=366 \times 3 + 9 \times 2 = 36。
    • [9, 6]:总和 = 9×3+6×2=399 \times 3 + 6 \times 2 = 39(不符合条件)。
  • 选择 [6, 9]

输出

[6, 9]

示例 3

输入

n = 9, max_value = 40, array = [1, 11, 13, 12, 7, 8, 11, 5, 6]

分析

  • 无法构成“葫芦”,返回 [0, 0]

输出

[0, 0]

时间复杂度

  1. 统计频率:O(n)O(n)。
  2. 筛选候选牌值:O(k)O(k),其中 kk 是牌值种类数(常数级,最多 13)。
  3. 枚举组合:O(p⋅q)O(p \cdot q),其中 p,qp, q 是三张牌和两张牌的候选数量(常数级)。
  4. 总复杂度:近似 O(n)O(n)。

总结

  • 代码实现充分利用了哈希表的快速统计能力,以及比较规则的优先级。
  • 特殊情况如 A 的优先级问题通过数值转换简单处理,逻辑清晰。