LeetCode: LCP 40. 心算挑战

心算挑战

原题

「力扣挑战赛」心算项目的挑战比赛中,要求选手从 N 张卡牌中选出 cnt 张卡牌,若这 cnt 张卡牌数字总和为偶数,则选手成绩「有效」且得分为 cnt 张卡牌数字总和。 给定数组 cards 和 cnt,其中 cards[i] 表示第 i 张卡牌上的数字。 请帮参赛选手计算最大的有效得分。若不存在获取有效得分的卡牌方案,则返回 0。

示例 1:

输入:cards = [1,2,8,9], cnt = 3

输出:18

解释:选择数字为 1、8、9 的这三张卡牌,此时可获得最大的有效得分 1+8+9=18。

示例 2:

输入:cards = [3,3,1], cnt = 1

输出:0

解释:不存在获取有效得分的卡牌方案。

提示:

1 <= cnt <= cards.length <= 10^5
1 <= cards[i] <= 1000

class Solution {
    public int maxmiumScore(int[] cards, int cnt) {
        
    }
}

解题思路

  1. 排序卡牌:将卡牌按照数字从大到小排序。
  2. 选择最大和的卡牌:从排序后的卡牌中选取前 cnt 张卡牌,如果这些卡牌的和为偶数,那么这是最大的有效得分。
  3. 调整选择:
    • 如果选出的 cnt 张卡牌和为奇数,我们需要替换其中一张卡牌,使得总和变为偶数。我们可以通过查找 cnt 张卡牌中最小的奇数,并将它替换为剩下卡牌中的最大偶数(或者反过来:查找最小的偶数,替换为最大的奇数),这样可能会得到一个有效的方案。
    • 如果没有符合条件的替换方案,那么返回 0。

代码示例

class Solution {
    public int maxmiumScore(int[] cards, int cnt) {
        int sum = 0;
        int length = cards.length;
        
        // 从大到小排序
        Arrays.sort(cards);

        // 将最后 cnt 个数相加
        for (int i = length - 1; i > length - cnt - 1; i--) {
            sum += cards[i];
        }

        // 判断奇偶性
        if (sum % 2 == 0) {
            return sum;
        } else {
            int minOddIn = -1;
            int minEvenIn = -1;
            int maxOddOut = -1;
            int maxEvenOut = -1;
            
            for (int i = length - 1; i >= length - cnt; i--) {
                // 寻找 cnt 内的最小偶数
                if (cards[i] % 2 == 0) {
                    if (minEvenIn == -1 || cards[i] < minEvenIn) {
                        minEvenIn = cards[i];
                    }
                } else {
                    // 寻找 cnt 内的最小奇数
                    if (minOddIn == -1 || cards[i] < minOddIn) {
                        minOddIn = cards[i];
                    }
                }
            }

            for (int i = length - cnt - 1; i >= 0; i--) {
                // 寻找 cnt 外的最大偶数
                if (cards[i] % 2 == 0) {
                    if (maxEvenOut == -1 || cards[i] > maxEvenOut) {
                        maxEvenOut = cards[i];
                    }
                } else {
                    // 寻找 cnt 外的最大奇数
                    if (maxOddOut == -1 || cards[i] > maxOddOut) {
                        maxOddOut = cards[i];
                    }
                }
            }

            // 修改结果
            int result1 = (minOddIn != -1 && maxEvenOut != -1) ? sum - minOddIn + maxEvenOut : -1;
            int result2 = (minEvenIn != -1 && maxOddOut != -1) ? sum - minEvenIn + maxOddOut : -1;

            // 选出最大值
            int maxSum = Math.max(result1, result2);

            return maxSum == -1 ? 0 : maxSum;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值