可获得的最大点数

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

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

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

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

示例 1:

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

示例 2:

复制代码
输入:cardPoints = [2,2,2], k = 2
输出:4
解释:无论你拿起哪两张卡牌,可获得的点数总是 4 。

示例 3:

复制代码
输入:cardPoints = [9,7,7,9,7,7,9], k = 7
输出:55
解释:你必须拿起所有卡牌,可以获得的点数为所有卡牌的点数之和。

示例 4:

复制代码
输入:cardPoints = [1,1000,1], k = 1
输出:1
解释:你无法拿到中间那张卡牌,所以可以获得的最大点数为 1 。 

示例 5:

复制代码
输入:cardPoints = [1,79,80,1,1,1,200,1], k = 3
输出:202

提示:

  • 1 <= cardPoints.length <= 10^5
  • 1 <= cardPoints[i] <= 10^4
  • 1 <= k <= cardPoints.length
题目解析:

题目的本质是从数组中挑选元素的组合,使组合的和最大。每次挑选的元素必须是开头的元素或结尾的元素。我们逆向思考去统计被挑省下来的元素的和sum最小,整个数组的和total固定,那么用total-sum得到的就是我们想要的答案。

注意:因为是逆向思维,所以我们要统计的子数组的长度为cardPoints.length-k。

解法思路:

逆向思维后,题目就变成了定长滑动窗口求子数组和最小的问题了,还是按照模板进行解题,同时注意我们题目要求的答案是total-sum。

代码:
cpp 复制代码
class Solution {
public:
    int maxScore(vector<int>& cardPoints, int k) {
        int ans=0,sum=0,total=0;
        int left=0,right=0;
        int n=cardPoints.size();
        for(auto e:cardPoints)
        {
            total+=e;
        }
        if (n-k == 0) return total;
        for(;right<n;right++)
        {
            sum+=cardPoints[right];
            if(right-left+1<n-k)
                continue;
            if(right-left+1>n-k)
                sum-=cardPoints[left++];
            ans=max(ans,total-sum);
        }
        return ans;
    }
};

注意:要特判k=n的情况,此时直接返回total就行

解法二:

正向思维,那么所挑选的数的组合就是

前k个

前k-1个+后1个

前k-2个+后2个

........

前1个+后k-1个

后k个

所以我们用前k个数的和初始化ans的值,从 i=1 开始枚举到 i=k,每次切换组合就让sum+=cardPoints[n−i]−cardPoints[k−i]。

然后更新返回最大的ans。

代码:
cpp 复制代码
class Solution {
public:
    int maxScore(vector<int>& cardPoints, int k) {
        int s=0;
        for(int i=0;i<k;i++)
        {
            s+=cardPoints[i];
        }
        int ans=s;
        for(int i=1;i<=k;i++)
        {
            s+=cardPoints[cardPoints.size()-i]-cardPoints[k-i];
            ans=max(s,ans);
        }
        return ans;
    }
};
相关推荐
songx_997 小时前
leetcode10(跳跃游戏 II)
数据结构·算法·leetcode
先做个垃圾出来………8 小时前
差分数组(Difference Array)
java·数据结构·算法
hansang_IR8 小时前
【题解】洛谷 P4286 [SHOI2008] 安全的航线 [递归分治]
c++·数学·算法·dfs·题解·向量·点积
乐迪信息8 小时前
乐迪信息:AI摄像机在智慧煤矿人员安全与行为识别中的技术应用
大数据·人工智能·算法·安全·视觉检测
多恩Stone9 小时前
【3DV 进阶-2】Hunyuan3D2.1 训练代码详细理解下-数据读取流程
人工智能·python·算法·3d·aigc
惯导马工10 小时前
【论文导读】IDOL: Inertial Deep Orientation-Estimation and Localization
深度学习·算法
老姜洛克10 小时前
自然语言处理(NLP)之n-gram从原理到实战
算法·nlp
CoovallyAIHub10 小时前
基于YOLO集成模型的无人机多光谱风电部件缺陷检测
深度学习·算法·计算机视觉
CoovallyAIHub10 小时前
几十个像素的小目标,为何难倒无人机?LCW-YOLO让无人机小目标检测不再卡顿
深度学习·算法·计算机视觉
怀旧,11 小时前
【C++】19. 封装红⿊树实现set和map
linux·c++·算法