Leetcode LCP40:心算挑战 (贪心算法)排序+简单数论知识

Leetcode LCP40:心算挑战 (贪心算法)排序+简单数论知识_第1张图片

    由题可知,我们可以从中知道选取的卡牌方案有两个要求:

  1.要求获取的卡牌方案总分得是偶数;

  2.要求获取的卡牌方案总分在要求1满足的情况下最大;

  不难想到:可以先对数组进行一个排序,我们可以先满足获取的卡牌方案满足总分最大,即从数组最后cnt项开始遍历累加,得到一个总数sum,如果,这个总数sum能整除2,那么就一定是满足题意的答案。如果不是的话,由我们的基础的数论知识可以得到——奇数-奇数+偶数=偶数或者是奇数-偶数+奇数=偶数。那如何保证重新取数后的数组是满足题意的最大值呢:那我们可以遍历剩下的数,找到剩下的数中最大的奇数和偶数,替换掉最后cnt项中最小的奇数和偶数。不妨将剩下的数中最大的奇数和最大的偶数定义为:maxOdd和maxEven,将最后cnt项最小的奇数和偶数定义为minOdd和minEven。毫无疑问,最大的符合要求的数必然是这两种情况之一:

  1.取出minOdd,加入maxEven,此时sum=sum-minOdd+maxEven;

  2.取出minEven,加入maxOdd,此时sum=sum-minEven+maxOdd;

  所以,我们需要的结果为Max(sum-minOdd+maxEven,sum-minEven+maxOdd)。

  由此,可以写出时间复杂度为O(N)的代码:

class Solution {

    public int maxmiumScore(int[] cards, int cnt) {       

    int sum=0;  //定义为排序后的数组后面cnt个数的和

    int mineven=0;//定义为排序后的数组后面cnt个数中最大的偶数

    int minodd=0;   //定义为排序后的数组后面cnt个数中最大的奇数

    int maxeven=0;  //定义为之后丢弃奇数取偶数的最大值

    int maxodd=0;      // 定义为之后丢弃偶数取奇数的最大值

    int flag1=0;

    int flag2=0;   

    Arrays.sort(cards);

    for(int i=cards.length-1;i>=cards.length-cnt;i--)

    {

        sum=sum+cards[i];

        if(cards[i]%2==0)

        mineven=cards[i];//最小的偶数

        else

        minodd=cards[i];//最小的奇数

    }

    if(sum%2==0)

    return sum;

    else

    {

        for(int i=cards.length-cnt-1;i>=0;i--)

        {

            if(cards[i]%2==1&&flag1==0&&mineven!=0)

            {

            maxodd=sum-mineven+cards[i];

            flag1=1;

            }

            if(cards[i]%2==0&&flag2==0&&minodd!=0)

            {

                maxeven=sum-minodd+cards[i];

                flag2=1;

            }

            if(flag1==1&&flag2==1)

            break;

        }

        if(flag1==0&&flag2==0)

        return 0;

        return Math.max(maxodd,maxeven);

    }

}

}

运行结果如下:

Leetcode LCP40:心算挑战 (贪心算法)排序+简单数论知识_第2张图片

 

 

你可能感兴趣的:(leetcode,数据结构,算法)