原题地址(中等)
方法1—滑动窗口
思路
代码
class Solution {
public:
int maxScore(vector<int>& cardPoints, int k) {
int n = cardPoints.size();
// 滑动窗口大小为 n-k
int windowSize = n - k;
// 选前 n-k 个作为初始值
int sum = accumulate(cardPoints.begin(), cardPoints.begin() + windowSize, 0);
int minSum = sum;
for (int i = windowSize; i < n; ++i) {
// 滑动窗口每向右移动一格,增加从右侧进入窗口的元素值,并减少从左侧离开窗口的元素值
sum += cardPoints[i] - cardPoints[i - windowSize];
minSum = min(minSum, sum);
}
return accumulate(cardPoints.begin(), cardPoints.end(), 0) - minSum;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/maximum-points-you-can-obtain-from-cards/solution/ke-huo-de-de-zui-da-dian-shu-by-leetcode-7je9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
时空复杂度
时间复杂度O(N) 空间复杂度O(1)
方法2—前缀后缀和
思路
虽然滑动窗口很妙,但是我也有自己的想法。
我的题解:
代码
class Solution {
public:
int maxScore(vector<int>& cardPoints, int k) {
int n = cardPoints.size();
vector<int> left(n, 0), right(n, 0);
// 计算left
for(int i = 0; i < n; i++) {
if(i > 0) left[i] = left[i-1] + cardPoints[i];
else left[i] = cardPoints[i];
}
// 计算right
for(int i = n - 1; i >= 0; i--) {
if(i == n - 1) right[i] = cardPoints[i];
else right[i] = right[i+1] + cardPoints[i];
}
// 遍历尝试
int ans = 0;
for(int i = 0; i <= k; i++) {
if(i == 0) ans = max(ans, right[n-k]);
else if(i == k) ans = max(ans, left[k-1]);
else ans = max(ans, left[i-1] + right[n-k+i]);
}
return ans;
}
};
时空复杂度
时间复杂度O(N) 空间复杂度O(N)