灵神题单滑动窗口可获得的最大点数(洛谷1423)思考题题解
原文链接:https://www.cnblogs.com/Time25/p/19670562.html
原题在此处解题思路
这道题的原题大致意思可以看上面链接,有一种做法是逆向思维,也就是,只能从首部或者尾部取一个数字,那么剩下的部分肯定是连续的,假设数组长度为n,要取的数字的个数为k,也就是求数组中
n-k个连续子数组的最小值,用总和减去最小值就可以得到最终的答案原题逆向思维解法代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 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;
}
};
```cpp
###原题灵神解法代码(两种)
**(https://leetcode.cn/problems/maximum-points-you-can-obtain-from-cards/solutions/2551432/liang-chong-fang-fa-ni-xiang-si-wei-zhen-e3gb/)**
##思考题解法
同理,思考题我们也可以这样做,就是求这个数组,这整个数组的最小字段和,后来了解,这种做法其实有一个专有的名字叫做**Kadane算法**
```cpp
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,可以求最大子数组,同样可解
这道题原题除了灵神的两种解法之外,还有另外一种解法,因为只能拿首部和尾部的牌,所以我们其实可以把这个数组给他变成一个环
1 | class Solution { |
写完啦,希望对你有帮助~
// TRAINING LOG · 第 12 / 76 篇训练记录 · 成文于 2026.03.04 · 深夜 23:58
本文是原创文章,采用CC BY-NC-SA 4.0许可协议,完整转载请注明来自FMAN720 / ALGO LOG
