力扣LCP 40. 心算挑战随笔

“一个能思想的人,才真是一个力量无边的人。”——巴尔扎克

题目

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

难度:简单

分析

        此题虽然标的简单,但是难度不小(做得人晕了😵),故此不得不记录,而且笔者的思路似乎不太好,没有官方的巧妙,受教了。

        笔者思路:由于偶数并不影响和的奇偶性,所以可以将奇数和偶数分开存储,将数值从大到小排序,开始时全部选择偶数(不够则加上奇数),每次加入一个大的奇数,移除一个小的偶数,判断总和的奇偶性更新结果。

        官方题解:将数组从大到小排列,取前cnt值的和,如果总和为偶数,直接返回;否则取以下两种情况中的较大值:cnt中最小的奇数与后面最大的偶数替换;cnt中最小的偶数与后面最大的奇数替换。

解答

奇偶分组

class Solution {
public:
    int maxmiumScore(vector<int>& cards, int cnt) {
        sort(cards.begin(),cards.end(),greater<int>());
        vector<int> odd,even;
        for (int i:cards){
            if (i%2==1){
                odd.push_back(i);
            }else{
                even.push_back(i);
            }
        }
        int i=0;  // odd
        int j=0;  // even
        int ans=0;
        int m=odd.size();
        int n=even.size();
        int cur=0;
        while (cnt&&j<n){
            cur+=even[j++];
            cnt--;
        }
        while (cnt&&i<m){
            cur+=odd[i++];
            cnt--;
        }
        if (cur%2==0){
            ans=cur;
        }
        while (i<m&&j-1>=0){
            cur+=odd[i++]-even[--j];
            if (cur%2==0){
                ans=max(ans,cur);
            }
        }
        return ans;
    }
};

奇偶替换

class Solution {
public:
    int maxmiumScore(vector<int>& cards, int cnt) {
        sort(cards.begin(),cards.end(),greater<int>());
        int ans=0;
        int cur=0;
        int minOdd=-1,minEven=-1;
        for (int i=0;i<cnt;i++){
            cur+=cards[i];
            if (cards[i]%2==1){
                minOdd=cards[i];
            }else{
                minEven=cards[i];
            }
        }
        if (cur%2==0){
            return cur;
        }
        for (int i=cnt;i<cards.size();i++){
            if (cards[i]%2==1){
                if (minEven!=-1){
                    ans=max(ans,cur-minEven+cards[i]);
                }
            }else{
                if (minOdd!=-1){
                    ans=max(ans,cur-minOdd+cards[i]);
                }
            }
        }
        return ans;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值