灵神题单滑动窗口可获得的最大点数(洛谷1423)思考题题解

原题在此处

解题思路

这道题的原题大致意思可以看上面链接,有一种做法是逆向思维,也就是,只能从首部或者尾部取一个数字,那么剩下的部分肯定是连续的,假设数组长度为n,要取的数字的个数为k,也就是求数组中
n-k个连续子数组的最小值,用总和减去最小值就可以得到最终的答案

原题逆向思维解法代码

class Solution {
public:
    int maxScore(vector<int>& cardPoints, int k) {
        int s=0,ans=INT_MAX;
        int nn=cardPoints.size();
        int n=nn-k;
        if(n==0){
            return accumulate(cardPoints.begin(),cardPoints.end(),0);
        }
        for(int i=0;i<cardPoints.size();i++){
            s+=cardPoints[i];
            if(i-n+1<0)continue;
            ans=min(ans,s);
            s-=cardPoints[i-n+1];
        }
        return accumulate(cardPoints.begin(),cardPoints.end(),0)-ans;
    }
};

原题灵神解法代码(两种)

https://leetcode.cn/problems/maximum-points-you-can-obtain-from-cards/solutions/2551432/liang-chong-fang-fa-ni-xiang-si-wei-zhen-e3gb/)

思考题解法

同理,思考题我们也可以这样做,就是求这个数组,这整个数组的最小字段和,后来了解,这种做法其实有一个专有的名字叫做Kadane算法

class Solution {
public:
    int maxScore(vector<int>& cardPoints, int k) {
        int cur=0,mn=0;
        int n=cardPoints.size();
        int s=accumulate(cardPoints.begin(),cardPoints.end(),0);
        for(int i=0;i<n;i++){
            cur=min(cur+cardPoints[i],cardPoints[i]);//意思是,是这个以第i+1个元素为结尾的子数组小,还是让这个第i-1个元素另起炉灶,成为新的子数组的开头
            mn=min(cur,mn);//从全局的角度,一直选出最小的子数组
        }
        return s-mn;
    }
};

如果将min换成max,可以求最大子数组,同样可解

这道题原题除了灵神的两种解法之外,还有另外一种解法,因为只能拿首部和尾部的牌,所以我们其实可以把这个数组给他变成一个环

class Solution {
public:
    int maxScore(vector<int>& cardPoints, int k) {
       int s=0;
       int cnt=0;
       int ans=0;
       for(int i=cardPoints.size()-k;i<cardPoints.size()+k;i++){
        s+=cardPoints[i%cardPoints.size()];
        cnt++;
        if(cnt<k)continue;
        ans=max(ans,s);
        s-=cardPoints[(i-k+1)%cardPoints.size()];
        cnt--;        
       }
       return ans;
    }
};

写完啦,希望对你有帮助~

posted @ 2026-03-04 23:58  Time_q  阅读(1)  评论(0)    收藏  举报