通过万岁!!!
- 题目:给你一个数组,然后让你从里面找cnt个数进行求和,要求最后和是一个偶数。如果不存在的话,那么返回0即可。
- 思路:最开始以为题目比较简单,就没太当回事,结果发现还比较麻烦。首先是看到这个题目要找最大值,想到了贪心。但是贪心的关键在于我们贪什么。这个题目比较麻烦的地方就是他贪的不是一个元素,而是两个元素的结果。首先我们要保证是个偶数,我们知道的是两个奇数或者两个偶数相加都是偶数,所以我们要每次找两个数,从而保证最后结果是一个偶数。并且我们要找最大的,那么就需要找最大的两个偶数和两个奇数。然后他们两个的和最大的,是我们本次贪心要的两个元素。需要注意的是,如果cnt是一个奇数,那么偶数的个数一定是奇数个。也就是我们需要先中一个最大的偶数。
- 技巧:贪心
java代码
class Solution {
public int maxmiumScore(int[] cards, int cnt) {
int length = cards.length, ret = 0;
// 第一大的奇数下标、第二大的奇数下标;第一大的偶数下标、第二大的偶数下标
int oddF = length - 1, oddS = length - 1, evenF = length - 1, evenS = length - 1;
int[] flags = new int[length];
Arrays.sort(cards);
// cnt是一个奇数,则先找下最大的偶数
if (cnt % 2 == 1) {
evenF = getFirstCard(cards, flags, evenF, 0);
if (evenF >= 0) {
ret = cards[evenF];
evenS = evenF;
cnt--;
flags[evenF] = 1;
} else {
return ret;
}
}
while (cnt > 0) {
oddF = getFirstCard(cards, flags, oddF, 1);
oddS = getSecondCard(cards, flags, oddF, 1);
evenF = getFirstCard(cards, flags, evenF, 0);
evenS = getSecondCard(cards, flags, evenF, 0);
if (oddS >= 0 && evenS >= 0) {
if (cards[oddF] + cards[oddS] >= cards[evenF] + cards[evenS]) {
flags[oddF] = 1;
flags[oddS] = 1;
ret += (cards[oddF] + cards[oddS]);
} else {
flags[evenF] = 1;
flags[evenS] = 1;
ret += (cards[evenF] + cards[evenS]);
}
cnt -= 2;
} else if (oddS < 0 && evenS < 0) {
return 0;
} else if (oddS < 0) {
flags[evenF] = 1;
flags[evenS] = 1;
ret += (cards[evenF] + cards[evenS]);
cnt -= 2;
} else {
flags[oddF] = 1;
flags[oddS] = 1;
ret += (cards[oddF] + cards[oddS]);
cnt -= 2;
}
}
return ret;
}
/**
* 获取第二大的元素下标
*
* @param cards
* @param flags
* @param begin
* @param remainder
* @return
*/
private int getSecondCard(int[] cards, int[] flags, int begin, int remainder) {
int flag = 0;
for (int i = begin; i >= 0; i--) {
if (cards[i] % 2 == remainder && flags[i] == 0) {
if (flag == 0) {
flag = 1;
} else {
return i;
}
}
}
return -1;
}
/**
* 获取第一大的元素下标
*
* @param cards
* @param flags
* @param begin
* @param remainder
* @return
*/
private int getFirstCard(int[] cards, int[] flags, int begin, int remainder) {
for (int i = begin; i >= 0; i--) {
if (cards[i] % 2 == remainder && flags[i] == 0) {
return i;
}
}
return -1;
}
}
- 总结:虽然是个简单题,但是题目还是比较难的。我的时间复杂度不太好,由于时间原因,通过万岁了。