[E模拟] lcLCP 40. 心算挑战(模拟+分类讨论+高质量模拟+代码实现)

1. 题目来源

链接:LCP 40. 心算挑战

2. 题目解析

挺有意思的一道分类讨论题目。如果纯是分类讨论的话,细节比较多,讨论清楚进行代码实现即可。

看到有一个前缀和解法的,也比较有意思。奇偶完全分类讨论,一直枚举偶数个奇数,保证结果是 偶数个奇数+偶数,用前缀和 O(1) 算出其和。挺不错的思路
见:

官方题解写了有哈希啥的,暂时没想看,跟题目给出的值域有关,通过哈希的方式,避免了排序,将时间复杂度做到了 O(n),但感觉在这没太大必要,有兴趣去研究下吧。


  • 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度 O ( 1 ) O(1) O(1)

class Solution {
public:
    int maxmiumScore(vector<int>& cards, int cnt) {
        int n = cards.size();
        sort(cards.begin(), cards.end());

        int i = n - 1;
        int res = 0;

        for (int j = 0; j < cnt; j ++ , i -- ) res += cards[i];    // 先统计最大的 cnt 个
        if ((res & 1) == 0) return res;   // 如果是偶数的话,直接返回

        // 统计前段的最大奇数、最大偶数
        // 替换逻辑是:
        //         找到后端最小的偶数,将它替换成前段的最大的奇数
        // 或者     找到后端最小的奇数,将它替换成前段的最大的偶数
        int ou = -1, ji = -1;
        for (int j = i; j >= 0; j -- ) {
            if (cards[j] & 1) ji = max(ji, cards[j]);
            else ou = max(ou, cards[j]);
        }
        
        int tou = -1, tji = -1;
        if (ou != -1) {
            // 去掉一个奇数,用前段最大偶数替换
            for (int j = i + 1; j < n; j ++ )
                if (cards[j] & 1) {
                    tou = res - cards[j] + ou;
                    break;
                }
        }
        if (ji != -1) {
            // 去掉一个偶数,用前段最大奇数替换
            for (int j = i + 1; j < n; j ++ ) 
                if ((cards[j] & 1) == 0) {
                    tji = res - cards[j] + ji;
                    break;
                }
        }

        // 如果没有执行替换逻辑,说明两个策略都没有满足执行条件,结果无法变成偶数,返回 0
        if (tou == -1 && tji == -1) return 0;

        // 执行替换逻辑,直接取 max 返回即可
        return max(tou, tji);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值