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 = 3Output:12Explanation: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 = 2Output:4Explanation: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 = 7Output:55Explanation: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 = 1Output:1Explanation: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 = 3Output: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;
}
}
```