Formatted question description: https://leetcode.ca/all/1423.html

# 1423. Maximum Points You Can Obtain from Cards (Medium)

There are several cards arranged in a row, and each card has an associated number of points The points are given in the integer array cardPoints.

In one step, you can take one card from the beginning or from the end of the row. You have to take exactly k cards.

Your score is the sum of the points of the cards you have taken.

Given the integer array cardPoints and the integer k, return the maximum score you can obtain.

Example 1:

Input: cardPoints = [1,2,3,4,5,6,1], k = 3
Output: 12
Explanation: After the first step, your score will always be 1. However, choosing the rightmost card first will maximize your total score. The optimal strategy is to take the three cards on the right, giving a final score of 1 + 6 + 5 = 12.


Example 2:

Input: cardPoints = [2,2,2], k = 2
Output: 4
Explanation: Regardless of which two cards you take, your score will always be 4.


Example 3:

Input: cardPoints = [9,7,7,9,7,7,9], k = 7
Output: 55
Explanation: You have to take all the cards. Your score is the sum of points of all cards.


Example 4:

Input: cardPoints = [1,1000,1], k = 1
Output: 1
Explanation: You cannot take the card in the middle. Your best score is 1.


Example 5:

Input: cardPoints = [1,79,80,1,1,1,200,1], k = 3
Output: 202


Constraints:

• 1 <= cardPoints.length <= 10^5
• 1 <= cardPoints[i] <= 10^4
• 1 <= k <= cardPoints.length

Related Topics:
Array, Dynamic Programming, Sliding Window

## Solution 1. Sliding Window

The cards selected must exist at the left edge or right edge of the array. So we can start from “selecting all cards from the right edge”, then select one card from left edge and remove one card from right, and so forth.

We use right as the sum of cards we selected at the right edge, and left as the sum of the cards at the left edge.

We start with computing the k elements at the right edge as right, then for each i in range [0, k), we add A[i] to left, and deduct A[N - k + i] from right, the result is the maximum left + right.

// OJ: https://leetcode.com/problems/maximum-points-you-can-obtain-from-cards/

// Time: O(K)
// Space: O(1)
class Solution {
public:
int maxScore(vector<int>& A, int k) {
int ans = 0, N = A.size(), left = 0, right = 0;
for (int i = 0; i < k; ++i) right += A[N - i - 1];
ans = right;
for (int i = 0; i < k; ++i) {
left += A[i];
right -= A[N - k + i];
ans = max(ans, left + right);
}
return ans;
}
};


Java

class Solution {
public int maxScore(int[] cardPoints, int k) {
int sum = 0;
int length = cardPoints.length;
for (int i = 0; i < length; i++)
sum += cardPoints[i];
int remain = length - k;
if (remain <= 0)
return sum;
int remainSum = 0;
for (int i = 0; i < remain; i++)
remainSum += cardPoints[i];
int minRemainSum = remainSum;
for (int i = remain; i < length; i++) {
remainSum -= cardPoints[i - remain];
remainSum += cardPoints[i];
minRemainSum = Math.min(minRemainSum, remainSum);
}
return sum - minRemainSum;
}
}