(贪心) LeetCode 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

二. 解题思路

1. 本题意思非常简单,需要从 cards 数组中选择 cnt 个数字相加,使得最后的结果为偶数的最大值。一看到最值问题,脑子一转—贪心!!!没错,就是它!

2. 既然要最大值,我们先给数组进行一个排序,从数组末尾累加 cnt 个值就可以了,但是还是要注意一个问题!如果累加之后的结果是偶数直接输出就好了,但是如果是奇数怎么办呢?

3. 这里聪明的小伙伴就会意识到,如果是奇数简单啊,我们只需要在剩余的数组中挑选一个最大的奇数和最大的偶数,然后在后面 cnt 个里面挑出来一个最小的奇数和最小的偶数,然后:

           (1). 将在数组前面找到的最大奇数与后 cnt 个数中最小的偶数进行替换;

           (2). 将在数组前面找到的最大偶数与后 cnt 个数中最小的奇数进行替换。

4. 上面两步骤执行之后结果就会成偶数了,然后判断一下哪个最大输出就可以了!!

话不多说!!!上代码!!

三. 代码

class Solution {
public:
    int maxmiumScore(vector<int>& cards, int cnt) {
        sort(cards.begin(), cards.end());
        
        int res = 0, ans = 0;
        int n = cards.size();
        int ji = -1, ou = -1;
        for(int i = n - 1; i >= n - cnt; i--){
            ans += cards[i];
            if(cards[i] % 2) ji = cards[i];     // 记录后 cnt 个中最小的奇数
            else ou = cards[i];                 // 记录后 cnt 个中最小的偶数
        }
        if(ans % 2 == 0) return ans;            // 如果是偶数直接输出
        else{
            for(int i = n - cnt - 1; i >= 0; i--){
                if(cards[i] % 2) {              // 前面部分的最大奇数
                    if(ou != -1) {              // 前提是必须保证后面 cnt 个数中必须有偶数,不然无法计算出偶数
                        res = max(res, ans - ou + cards[i]);
                    }
                }else{                          // 同上
                    if(ji != -1){
                        res = max(res, ans - ji + cards[i]);
                    }
                }
            }
        return res;
        }
    }
};

四. 总结

本题考查贪心思想,是一道很好的题目,建议练习!!!

时间复杂度:O(n*logn)(其中n为数组长度);

空间复杂度:O(1);

喜欢的话给个关注吧!!

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值