今天桌游输了二十几,省吃俭用的我心态爆炸QAQ
题目描述
错误示范
觉得那边大就取哪边,直到取到k个数,今天一直都蠢蠢的
反例
[11,49,100,20,86,29,72]
4
这样的思路会得出 72 - 29 - 86 - 20,但实际上是 72 - 11 - 49 - 100
class Solution {
public:
int maxScore(vector<int>& cardPoints, int k) {
int i = 0, j = cardPoints.size() - 1;
int ans = 0;
while(k > 0) {
if(cardPoints[i] == cardPoints[j]) {
while(k > 1 && cardPoints[i + 1] == cardPoints[j - 1]) {
ans += cardPoints[i];
i++;
j--;
k--;
cout<<"i:"<<i<<" "<<"j:"<<j;
cout<<"k:"<<k<<endl;
}
if(k > 0) {
if(cardPoints[i] > cardPoints[j]) {
ans += cardPoints[i];
i++;
} else {
ans += cardPoints[j];
j--;
}
k--;
}
} else if(cardPoints[i] > cardPoints[j]) {
ans += cardPoints[i];
i++;
k--;
}
else {
ans += cardPoints[j];
j--;
k--;
}
}
return ans;
}
};
其中这里还犯了一个错误
while(k > 0) {
if(cardPoints[i] == cardPoints[j]) {
while(k > 1 && cardPoints[i + 1] == cardPoints[j - 1]) {
ans += cardPoints[i];
i++;
j--;
k--;
cout<<"i:"<<i<<" "<<"j:"<<j;
cout<<"k:"<<k<<endl;
}
这里while部分一开始写成 k > 0;
如例子
[9,7,7,9,7,7,9] k = 7
k一共需要执行七次--
运算循环才会停止,这时候i+1就越界了。
正确思路 滑动窗口
由于每次只取最前或者最后面的数,所以最后剩下来的数一定是连续的:
保证剩下来的数总和最小,就能保证取出来的数总和最大
所以题目就变成求合最小的滑动窗口区间,并且大小是固定的。
class Solution {
public:
int maxScore(vector<int>& cardPoints, int k) {
int len = cardPoints.size();
int acount = accumulate(cardPoints.begin(), cardPoints.end() , 0);
if(k == len) {
return acount;
}
int count = 0;
for(int i = 0; i < len - k; i++) {
count += cardPoints[i];
}
int res = count;
for(int i = len - k; i < len; i++) {
count = count + cardPoints[i] - cardPoints[i - (len - k )];
res = min(res, count);
}
return acount - res;
}
};
时间复杂度O(n)
空间复杂度O(1)
len - k就是我们需要的滑动窗口的大小