来啦大葫芦:5.寻找最大葫芦

87 阅读2分钟

5.寻找最大葫芦


function solution(n, max, array) {
    // Edit your code here
    // 由于顺序是 A>K>Q>J等顺序
    const cardValueMap = {
        1: 14, // 1 (A) 映射为 14
        2: 2,
        3: 3,
        4: 4,
        5: 5,
        6: 6,
        7: 7,
        8: 8,
        9: 9,
        10: 10,
        11: 11,
        12: 12,
        13: 13,
        0: 0
    };
    const count = {};
    // 统计每张牌的出现次数
    for (const card of array) {
        count[card] = (count[card] || 0) + 1;
    }

    // 生成候选列表:a需要至少3次,b需要至少2次,并按牌面降序排列
    const aCandidates = Object.keys(count)
        .map(Number)
        .filter(k => count[k] >= 3)
        .sort((a, b) => cardValueMap[b] - cardValueMap[a]); //从小到大排列

    const bCandidates = Object.keys(count)  // 2位数
        .map(Number)
        .filter(k => count[k] >= 2)
        .sort((a, b) => cardValueMap[b] - cardValueMap[a]);

    let maxA = 0;
    let maxB = 0;


    // console.log('3次以上元素,2次以上元素:',aCandidates, bCandidates)
    // 遍历所有可能的3次元素
    for (const a of aCandidates) {
        const remaining = max - 3 * a;
        if (remaining < 0) continue; // 总和超过限制,跳过

        const maxBVal = Math.floor(remaining / 2); // b的最大允许值
        let currentB = 0;

        // 寻找最大的合法b(已排序,第一个满足条件的即最大)
        for (const b of bCandidates) {
            if (b === a && count[a] < 4) continue; // b不能和a相同
            const realb = b
            if (realb <= maxBVal) {
                currentB = b;
                break;
            }
        }
        // console.log('B:', a, currentB)
        // 更新最大值
        if (currentB > 0) {
            // 比较 A 和 B 的大小,赋给 maxA 和 maxB
            if (cardValueMap[a] > cardValueMap[maxA] || (cardValueMap[a] === cardValueMap[maxA] && cardValueMap[currentB] > cardValueMap[maxB])) {
                maxA = a;
                maxB = currentB;
            }
        }
    }
    // console.log('最大值:', maxA, maxB)
    return (maxA !== 0 || maxB !== 0) ? [maxA, maxB] : [0, 0];
}

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(31, 42, [3, 3, 11, 12, 12, 2, 13, 5, 13, 1, 13, 8, 8, 1, 8, 13, 12, 9, 2, 11, 3, 5, 8, 11, 1, 11, 1, 5, 4, 2, 5])) === JSON.stringify([1, 13]));
}

main();

时间复杂度:

1.for 循环遍历 array 数组,统计每张牌的出现次数。这个操作的时间复杂度是 O(n),其中 n 是数组的长度。

2.aCandidates 和 bCandidates 列表。这两个操作都涉及到遍历 count 对象的键,并进行排序。假设 count 对象中有 k 个不同的牌面值,那么生成候选列表的时间复杂度是 O(k log k)

3.最后对 aCandidates 和 bCandidates 的遍历: 假设 aCandidates 中有 m个元素,bCandidates 中有 n 个元素,那么这个操作的时间复杂度是 O(m * n)

空间复杂度:

  1. 代码中使用了 count 对象来存储每张牌的出现次数。这个对象的空间复杂度是 O(k),其中 k 是不同的牌面值的数量。

  2. 生成候选列表: 代码中生成了 aCandidates 和 bCandidates 列表。这两个列表的空间复杂度分别是 O(m) 和 O(n),其中 m 和 n 分别是 aCandidates 和 bCandidates 的长度。 因此空间复杂度是 O(n)