LeetCode——LCP 40. 心算挑战赛

通过万岁!!!

  • 题目:给你一个数组,然后让你从里面找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;
    }
}
  • 总结:虽然是个简单题,但是题目还是比较难的。我的时间复杂度不太好,由于时间原因,通过万岁了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值