LeetCode: 5393. 可获得的最大点数 C语言版

LeetCode: 5393. 可获得的最大点数 C语言版

题目:
几张卡牌 排成一行,每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。

每次行动,你可以从行的开头或者末尾拿一张卡牌,最终你必须正好拿 k 张卡牌。

你的点数就是你拿到手中的所有卡牌的点数之和。

给你一个整数数组 cardPoints 和整数 k,请你返回可以获得的最大点数。

示例 1:

输入:cardPoints = [1,2,3,4,5,6,1], k = 3
输出:12
解释:第一次行动,不管拿哪张牌,你的点数总是 1 。但是,先拿最右边的卡牌将会最大化你的可获得点数。最优策略是拿右边的三张牌,最终点数为 1 + 6 + 5 = 12 。

解:
其实这个题的解法还是很多的,我一开始想的是直接i从0循环到k,然后在循环里面分别写两个循环,一个是左边取i个数相加,一个是右边取k-i个数相加。然后给一个max,在这些循环中找到最大值,但是这样的时间复杂度就很大,妥妥的O(K^2),所以运行后时间超时。然后改进之后选择这么写。

int maxScore(int* cardPoints, int cardPointsSize, int k)
{
    int max = 0;
    int i , j , x = 0;
    //存储左边和右边的值
    int left[100000] = {0} , right[100000] = {0};
	
	/*当取的k与卡片数相同时,直接返回所有卡牌之和*/
    if(cardPointsSize <= k)
    {
        for(i = 0 ; i < cardPointsSize ; i++ )
            max = max + cardPoints[i];   
        return max;
    }
     
	/*当只取一次卡牌时,返回左或右的最大值*/ 
    if(k == 1)
        return cardPoints[0] > cardPoints[cardPointsSize - 1] ? cardPoints[0] : cardPoints[cardPointsSize - 1];  
    
    j = 1;
    /*从左边取0到k次的和存入数组*/
    for(i = 0 ; i <= k ; i++)
        left[j++] = left[i] + cardPoints[i];
    
    i = 1;
    /*从右边取0到k次的和存入数组*/   
    for(j = cardPointsSize - 1 ; j > cardPointsSize - 1 - k ; j--)
        right[i++] = right[x++] + cardPoints[j];   
    
    /*从左边取i次,右边取k-i次,返回最大值*/
    for( i = 0 ; i <= k ; i++)
        max = left[i] + right[k-i] > max ? left[i] + right[k-i] : max;
    
    return max;      
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值