Maximum Points You Can Obtain from Cards
There are several cards arranged in a row, each with a point value, and an integer k. In one step you take one card from the beginning or the end of the row. After exactly k steps, return the maximum total of the points on the cards you took . Taking k cards from the ends is the same as leaving behind one contiguous block in the middle, so find the minimum-sum window of size (n - k) and subtract it from the total.
Constraints
- 1 ≤ cardPoints.length ≤ 105
- 1 ≤ cardPointsi ≤ 104
- 1 ≤ k ≤ cardPoints.length
Example
cardPoints = [1, 2, 3, 4, 5, 6, 1], k = 312Explanation Taking the last three cards (5, 6, 1) scores 12, the best possible for k = 3.
Total minus the minimum leftover window
Leftover window [1,2,3,4] sums to 10 — current minimum.
What happens in this step
n=7, k=3 → leftover window size = n - k = 4 initial window = cardPoints[0..3] = [1,2,3,4], sum = 10 minWindow = 10 (starting value, nothing to compare yet)
Steps to visualize
- Sum every card to get the total, then compute the sum of the first n - k cards as the starting leftover window.
- Slide the leftover window one step at a time: add the entering card, remove the leaving card.
- Track the minimum leftover window sum seen.
- That minimum window is the block of cards you never touch.
- The answer is the total minus that minimum leftover sum.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
Leftover window [1,2,3,4] sums to 10 — current minimum.
What happens in this step
n=7, k=3 → leftover window size = n - k = 4 initial window = cardPoints[0..3] = [1,2,3,4], sum = 10 minWindow = 10 (starting value, nothing to compare yet)
Solution
function maxScore(cardPoints, k) {
const n = cardPoints.length;
const total = cardPoints.reduce((sum, val) => sum + val, 0);
const windowSize = n - k;
if (windowSize <= 0) return total;
let windowSum = 0;
for (let i = 0; i < windowSize; i++) {
windowSum += cardPoints[i];
}
let minWindow = windowSum;
for (let right = windowSize; right < n; right++) {
windowSum += cardPoints[right] - cardPoints[right - windowSize];
minWindow = Math.min(minWindow, windowSum);
}
return total - minWindow;
}- Time
- O(n)
- Space
- O(1)
Test cases
| Input | Expected | Covers |
|---|---|---|
cardPoints = [1, 2, 3, 4, 5, 6, 1], k = 3 | 12 | Docstring example |
cardPoints = [1, 2, 3, 4, 5, 6, 1], k = 0 | 0 | k = 0 takes no cards |
cardPoints = [1, 2, 3, 4, 5, 6, 1], k = 7 | 22 | k equals array length — take every card |
cardPoints = [5], k = 1 | 5 | Single card, take it |
cardPoints = [5], k = 0 | 0 | Single card, take none |
cardPoints = [2, 2, 2], k = 2 | 4 | Identical values, any two work |
cardPoints = [1, 79, 80, 1, 1, 1, 200, 1], k = 3 | 202 | Best score comes from splitting front and back picks |