问题解析
在经典德州扑克的“葫芦”牌型基础上,添加了限制条件:组成“葫芦”的五张牌总和不能超过给定的最大值 max_value。任务是找到一个符合条件的“葫芦”组合,优先比较三张牌(a),然后比较两张牌(b)。如果不存在符合条件的组合,则返回 [0, 0]。
解题思路
-
统计牌频率:
-
使用
collections.Counter统计每种牌的频率。 -
筛选出满足条件的牌值列表:
- 至少出现 3 次的牌作为“三张”候选。
- 至少出现 2 次的牌作为“两张”候选。
-
-
枚举所有可能的组合:
-
遍历“三张”候选列表,与“两张”候选列表两两组合,判断是否满足“葫芦”的限制条件。
-
确保:
- 三张与两张牌值可以是相同,但需满足总数足够构成“葫芦”(至少 5 张)。
- 总和不超过
max_value。
-
-
比较规则:
-
若多个组合符合条件,则按如下顺序选择最优组合:
- 首先比较三张牌值(A=1 为最大,K=13,Q=12,...)。
- 若三张牌值相同,再比较两张牌值。
-
-
处理 A 的特殊性:
- 在德州扑克中,A 的牌值为 1,但在比较大小时需视为最大牌值(等效于 14),需在比较时调整。
-
输出结果:
- 如果找到符合条件的“葫芦”,输出
[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]
时间复杂度
- 统计频率:O(n)O(n)。
- 筛选候选牌值:O(k)O(k),其中 kk 是牌值种类数(常数级,最多 13)。
- 枚举组合:O(p⋅q)O(p \cdot q),其中 p,qp, q 是三张牌和两张牌的候选数量(常数级)。
- 总复杂度:近似 O(n)O(n)。
总结
- 代码实现充分利用了哈希表的快速统计能力,以及比较规则的优先级。
- 特殊情况如 A 的优先级问题通过数值转换简单处理,逻辑清晰。