寻找最大葫芦(javascript版)-豆包marscode算法刷题

174 阅读4分钟

问题描述

在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 aa 和另外两张相同牌面值的牌 bb。如果两个人同时拥有“葫芦”,我们会优先比较牌 aa 的大小,若牌 aa 相同则再比较牌 bb 的大小,牌面值的大小规则为:1 (A) > K > Q > J > 10 > 9 > ... > 2,其中 1 (A) 的牌面值为1,K 为13,依此类推。

在这个问题中,我们对“葫芦”增加了一个限制:组成“葫芦”的五张牌牌面值之和不能超过给定的最大值 max。

给定一组牌,你需要找到符合规则的最大的“葫芦”组合,并输出其中三张相同的牌面和两张相同的牌面。如果找不到符合条件的“葫芦”,则输出 “0, 0”。

测试样例

样例1:

输入:n = 9, max = 34, array = [6, 6, 6, 8, 8, 8, 5, 5, 1]
输出:[8, 5]
说明:array数组中可组成4个葫芦,分别为[6,6,6,8,8],[6,6,6,5,5],[8,8,8,6,6],[8,8,8,5,5]。其中[8,8,8,6,6]的牌面值为36,大于34不符合要求。剩下的3个葫芦的大小关系为[8,8,8,5,5]>[6,6,6,8,8]>[6,6,6,5,5],故返回[8,5]

样例2:

输入:n = 9, max = 37, array = [9, 9, 9, 9, 6, 6, 6, 6, 13]
输出:[6, 9]
说明:可组成2个葫芦,分别为[9,9,9,6,6]和[6,6,6,9,9],由于[9,9,9,6,6]的牌面值为39,大于37,故返回[6,9]

样例3:

输入:n = 9, max = 40, array = [1, 11, 13, 12, 7, 8, 11, 5, 6]
输出:[0, 0]
说明:无法组成任何葫芦,故返回[0,0]

样例4:

输入:n = 6, max = 50, array = [13, 13, 13, 1, 1, 1]
输出:[1, 13]
说明:可组成两个葫芦,分别为[A,A,A,K,K]和[K,K,K,A,A],两者牌面值都小于50,故都合法。因为三张相同牌面值的A > K,故[A,A,A,K,K]比[K,K,K,A,A]要大,返回[1,13]

题解


function solution(n, max, array) {
    // 牌面值映射
    const valueMap = {
        1: 14,  // A
        13: 13, // K
        12: 12, // Q
        11: 11, // J
        10: 10, // 10
        9: 9,   // 9
        8: 8,   // 8
        7: 7,   // 7
        6: 6,   // 6
        5: 5,   // 5
        4: 4,   // 4
        3: 3,   // 3
        2: 2    // 2
    }
    // 统计每个牌面值的出现次数
    const countMap = {};
    for (let card of array) {
        countMap[card] = (countMap[card] || 0) + 1;
    }

    // 初始化结果
    let bestTriple = 0;
    let bestPair = 0;

    // 遍历每个牌面值,尝试生成“葫芦”组合
    for (let a in countMap) {
        a = parseInt(a);
        if (countMap[a] >= 3) {
            // 找到三张相同的牌 a
            for (let b in countMap) {
                b = parseInt(b);
                if (b !== a && countMap[b] >= 2) {
                    // 找到两张相同的牌 b
                    const sum = 3 * a + 2 * b;
                    if (sum <= max) {
                        // 判断是否是当前最好的“葫芦”组合
                        if (bestTriple === 0 && bestPair === 0) {
                            bestTriple = a;
                            bestPair = b;
                        }
                        if (valueMap[a] > valueMap[bestTriple] || (valueMap[a] === valueMap[bestTriple] && valueMap[b] > valueMap[bestPair])) {
                            bestTriple = a;
                            bestPair = b;
                        }
                    }
                }
            }
        }
    }

    // 如果没有找到符合条件的“葫芦”,返回 [0, 0]
    if (bestTriple === 0 && bestPair === 0) {
        return [0, 0];
    }

    return [bestTriple, bestPair];
}

function main() {
    // Add your test cases here
    console.log(JSON.stringify(solution(9, 34, [6, 6, 6, 8, 8, 8, 5, 5, 1])) === JSON.stringify([8, 5]));
    console.log(JSON.stringify(solution(9, 37, [9, 9, 9, 9, 6, 6, 6, 6, 13])) === JSON.stringify([6, 9]));
    console.log(JSON.stringify(solution(9, 40, [1, 11, 13, 12, 7, 8, 11, 5, 6])) === JSON.stringify([0, 0]));
    console.log(JSON.stringify(solution(6, 50, [13, 13, 13, 1, 1, 1])) === JSON.stringify([1, 13]));
}

main();

解题思路

  1. 牌面值映射

    • 创建了一个 valueMap 来映射牌面值的大小,特别是 A 对应 14。因为A>k,k对应的值为13,便于比较将A赋值为14。
  2. 统计每个牌面值的出现次数

    • 使用 countMap 来统计每个牌面值的出现次数。
  3. 遍历每个牌面值,尝试生成“葫芦”组合

    • 遍历每个牌面值 a,检查它是否可以作为三张相同牌面值的牌。
    • 对于每个 a,再遍历每个牌面值 b,检查它是否可以作为两张相同牌面值的牌。
    • 确保 a 和 b 不相同。
  4. 计算组合的牌面值之和

    • 计算 3 * a + 2 * b 的值,并检查是否小于等于 max
  5. 比较“葫芦”组合

    • 如果当前组合的牌面值之和小于等于 max,则比较它与当前最好的“葫芦”组合。
    • 优先比较三张相同牌面值的大小,如果相同则比较两张相同牌面值的大小。
  6. 返回结果

    • 如果没有找到符合条件的“葫芦”,则返回 [0, 0]