medium

Maximum Points You Can Obtain from Cards

Take exactly k cards from either end of a row to maximize their total value.

1. Define the problem

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

InputcardPoints = [1, 2, 3, 4, 5, 6, 1], k = 3
Output12

Explanation Taking the last three cards (5, 6, 1) scores 12, the best possible for k = 3.

2. Visualize the solution

Total minus the minimum leftover window

Total minus the minimum leftover window
Statusbest

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)
Step 1 of 4

Steps to visualize

  1. Sum every card to get the total, then compute the sum of the first n - k cards as the starting leftover window.
  2. Slide the leftover window one step at a time: add the entering card, remove the leaving card.
  3. Track the minimum leftover window sum seen.
  4. That minimum window is the block of cards you never touch.
  5. The answer is the total minus that minimum leftover sum.
3. Walk through the code

Walk through the code

Same walkthrough, now with the code. Press Next to move one step and watch which lines run.

Total minus the minimum leftover window
Statusbest

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)
Step 1 of 4
4. Solution

Solution

solution.tsTypeScript
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)
5. Test cases

Test cases

InputExpectedCovers
cardPoints = [1, 2, 3, 4, 5, 6, 1], k = 312Docstring example
cardPoints = [1, 2, 3, 4, 5, 6, 1], k = 00k = 0 takes no cards
cardPoints = [1, 2, 3, 4, 5, 6, 1], k = 722k equals array length — take every card
cardPoints = [5], k = 15Single card, take it
cardPoints = [5], k = 00Single card, take none
cardPoints = [2, 2, 2], k = 24Identical values, any two work
cardPoints = [1, 79, 80, 1, 1, 1, 200, 1], k = 3202Best score comes from splitting front and back picks