一、题目描述
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
二、解题思路
* 1、先对数组进行升序排序
* 2、找到最后cnt个数字,累加得到了一个最大数字,如果是偶数,那么直接返回,
* 3、如果是奇数,那么分以下两种情况
* 第一种:在cnt个数字中找到最小的偶数,然后将这个最小的偶数替换为cnt个数字之外的最大的奇数
* 第二种:在cnt个数字中找到最小的奇数,然后将这个最小的技术替换为cnt个数字之外的最大的奇数
* 4、这样这个原来是奇数的数字就一定会变成偶数,然后再取这两个数字中最大的那个返回
三、代码示例
public static void main(String[] args) {
//测试用例
// int[] cards = {1,3,4,6,8,9};
int[] cards = {1,3,4,6,8,9,9,10};
int cnt = 2;
int result = maxmiumScore(cards,cnt);
System.out.println(result);
}
private static int maxmiumScore(int[] cards, int cnt) {
//排序
Arrays.sort(cards);
//第一次为偶数的最大有效分数
int temp = 0;
//第一次为奇数的最大有效分数
int ans = 0;
//第一次选中cnt个数字中最小的奇数
int odd = -1;
//第一次选中cnt个数字中最小的偶数
int even = -1;
//从最后一个数开始累加,加到倒数第cnt个数结束
for (int i = cards.length - 1; i > cards.length - cnt - 1 ; i --) {
temp += cards[i];
//最后一次赋值的就是cnt中最小的奇数
if ((cards[i] & 1) == 1) {
odd = cards[i];
}
//最后一次赋值的就是cnt中最小的偶数
if ((cards[i] & 1) == 0) {
even = cards[i];
}
}
//如果temp是偶数,则直接返回
if ((temp & 1) == 0) {
return temp;
}
//如果是奇数,则分两种情况
//1、将cnt中最小的偶数替换成cnt之外的最大的奇数
for (int i = cards.length - cnt - 1; i >= 0; i --) {
if ((cards[i] & 1) == 1) {
if (even != -1) {
ans = Math.max(ans, temp - even + cards[i]);
break;
}
}
}
//2、将cnt中最小的奇数替换成cnt之外的最大的偶数
for (int i = cards.length - cnt - 1; i >= 0; i --) {
if ((cards[i] & 1) == 0) {
if (odd != -1) {
ans = Math.max(ans, temp - odd + cards[i]);
break;
}
}
}
return ans;
}