青训营 X 豆包 MarsCode 技术训练营第二课 寻找最大葫芦 | 豆包 MarsCode AI 刷题

110 阅读3分钟

在德州扑克游戏中,“葫芦”是一种非常强大的牌型,由三张相同牌面值的牌和另外两张相同牌面值的牌组成。在这个问题中,我们需要找到符合规则的最大的“葫芦”组合,并且牌面值之和不能超过给定的最大值。这个问题不仅考察了我们对数据结构的理解,还考察了我们的算法设计能力和对复杂度的控制。

一、问题分析

  1. 输入参数

    • n:牌的总数。
    • max:葫芦牌面值之和的最大值。
    • array:包含牌面值的数组。
  2. 输出结果

    • 如果找到符合条件的葫芦,输出其中三张相同的牌面和两张相同的牌面。
    • 如果找不到,输出 [0, 0]
  3. 约束条件

    • 牌面值的大小规则为:A > K > Q > J > 10 > 9 > ... > 2,其中 A 的牌面值为1,K 为13,依此类推。
    • 牌面值之和不能超过 max

二、算法设计

为了解决这个问题,我们可以采用以下步骤:

  1. 统计频率:首先,我们需要统计每张牌在数组中出现的频率。这可以通过哈希表来实现。

  2. 排序:将牌面值从大到小排序,这样可以优先找到最大的葫芦组合。

  3. 查找葫芦:遍历排序后的牌面值,对于每个牌面值 a,检查是否存在频率至少为3的 a,并且存在另一个牌面值 b,使得 b 的频率至少为2,并且 3a + 2b <= max

  4. 更新结果:如果找到符合条件的葫芦,更新结果并继续查找,直到遍历完所有可能的组合。

三、算法实现

以下是算法的伪代码:

def find_max_gourd(n, max, array):
    from collections import Counter
    
    # 统计每张牌的频率
    freq = Counter(array)
    
    # 牌面值从大到小排序
    sorted_cards = sorted(freq.keys(), reverse=True)
    
    # 初始化结果
    result = [0, 0]
    
    # 查找最大的葫芦
    for a in sorted_cards:
        if freq[a] >= 3:
            for b in sorted_cards:
                if a != b and freq[b] >= 2 and 3 * a + 2 * b <= max:
                    result = [a, b]
                    return result
    
    return result

四、测试样例验证

为了验证算法的正确性,我使用了几组测试样例:

  • 样例1:输入 n = 9, max = 34, array = [6, 6, 6, 8, 8, 8, 5, 5, 1],输出 [8, 5],验证了算法能够正确处理多个符合条件的葫芦的情况。

  • 样例2:输入 n = 9, max = 37, array = [9, 9, 9, 9, 6, 6, 6, 6, 13],输出 [6, 9],验证了算法能够正确处理牌面值较大的情况。

  • 样例3:输入 n = 9, max = 40, array = [1, 11, 13, 12, 7, 8, 11, 5, 6],输出 [0, 0],验证了算法能够正确处理找不到符合条件的葫芦的情况。

五、总结

通过这个问题的解决,我深刻体会到了算法设计中的几个关键点:

  1. 数据结构的选择:使用哈希表来统计频率,大大提高了查找效率。

  2. 排序的重要性:通过排序,我们可以优先处理最大的牌面值,从而找到最大的葫芦组合。

  3. 复杂度的控制:虽然我们使用了嵌套循环,但由于排序和哈希表的使用,整体时间复杂度仍然控制在可接受的范围内。

这次解题经历不仅提高了我的编程能力,也加深了我对算法设计和数据结构的理解。