Skip to content
← All posts

Maximum Points You Can Obtain from Cards: Sliding Window on Edges

5 min read
leetcodeproblemmediumarrayssliding-window

You are given an array of integers cardPoints where cardPoints[i] is the point value of the i-th card. In one step, you can take a card from either the beginning or the end of the array. You must take exactly k cards. Your goal is to maximize the total points you collect.

This is LeetCode 1423: Maximum Points You Can Obtain from Cards, a medium problem that teaches you how to reframe an edge-selection problem as a sliding window problem on the interior of an array.

cardPoints = [1, 2, 3, 4, 5, 6, 1], k = 310213243546516left: 1right: 6 + 1total picked = 1 + 6 + 1 = 8 (maximum)
Green cards are selected from the edges. You pick k = 3 cards total from the left and right ends to maximize the sum.

Why this problem matters

Picking from both ends of an array is a pattern that shows up in card games, scheduling, and resource allocation problems. The naive approach of trying every combination of left and right picks is exponential. The sliding window reframe is the kind of insight that turns an intractable problem into a linear-time solution, and it appears in many variations across competitive programming and interviews.

The key insight

Instead of thinking about which k cards to pick from the edges, think about which n - k cards to leave in the middle. The cards you leave behind form a contiguous subarray. If you minimize the sum of that middle subarray, you maximize the sum of the cards you pick.

So the problem reduces to: find the contiguous subarray of length n - k with the minimum sum. The answer is total_sum - min_window_sum.

The solution

def maxScore(cardPoints, k):
    n = len(cardPoints)
    window_size = n - k
    window_sum = sum(cardPoints[:window_size])
    min_sum = window_sum
    total = sum(cardPoints)

    for i in range(window_size, n):
        window_sum += cardPoints[i] - cardPoints[i - window_size]
        min_sum = min(min_sum, window_sum)

    return total - min_sum

First you compute the total sum of all cards and the sum of the first n - k elements as your initial window. Then you slide that window one position to the right on each iteration: add the new element entering the window and subtract the element leaving it. Track the minimum window sum you see. At the end, subtract the minimum window sum from the total to get your answer.

When a problem asks you to pick elements from both ends of an array, try flipping the question: what contiguous subarray are you leaving behind? This "complement" reframe often converts a tricky two-pointer problem into a clean sliding window.

Visual walkthrough

Window position 1: middle = [1, 2, 3, 4]

1234561window sum = 10, picked = 12

Window covers indices 0 through 3. Window sum = 10, so picked sum = 22 - 10 = 12. But this means picking 3 cards from the right only.

Window position 2: middle = [2, 3, 4, 5]

1234561window sum = 14, picked = 8

Slide window right by one. Window sum = 14, picked sum = 22 - 14 = 8. Pick 1 from left, 2 from right.

Window position 3: middle = [3, 4, 5, 6]

1234561window sum = 18, picked = 4

Window sum = 18, picked sum = 22 - 18 = 4. Pick 2 from left, 1 from right.

Window position 4: middle = [4, 5, 6, 1]

1234561window sum = 16, picked = 6

Window sum = 16, picked sum = 22 - 16 = 6. Pick 3 from left, 0 from right.

Result: minimum window sum is 10 (position 1), so maximum points = 22 - 10 = 12.

This corresponds to picking all 3 cards from the right: 5 + 6 + 1 = 12.

Each step slides the "leave behind" window one position to the right. The green cards outside the window are the ones you pick. The window with the smallest sum gives you the largest pick, which is the answer.

Complexity analysis

ApproachTimeSpace
Sliding windowO(n)O(1)

The initial sum call takes O(n). The sliding window loop also takes O(n). Together that is O(n) time. You only store a handful of variables (window sum, minimum sum, total), so space is O(1).

The building blocks

1. Fixed-size sliding window

The core mechanic is maintaining a sum over a window of fixed length. As the window slides, you add the incoming element and remove the outgoing element. This keeps each update at O(1) instead of recomputing the sum from scratch.

window_sum = sum(arr[:w])
for i in range(w, n):
    window_sum += arr[i] - arr[i - w]

This pattern appears in problems like Maximum Average Subarray, Minimum Size Subarray Sum, and any problem where you need to evaluate a property over every contiguous subarray of a given length.

2. Complement reframing

Instead of maximizing what you pick, you minimize what you leave behind. This works whenever the total is fixed and your selection must cover the entire array. The complement of your selection is a contiguous subarray, which is much easier to optimize over.

answer = total - min_window_sum

This reframe shows up in problems like Minimum Operations to Reduce X to Zero, where subtracting from both ends is equivalent to finding a subarray with a target sum in the middle.

Edge cases

  • k equals n: you must take every card. The answer is simply the sum of all elements. The window size is 0, and the minimum window sum is 0, so the formula still works.
  • All cards have the same value: every combination of k picks yields the same total. The sliding window will find every window sum is equal, and the result is k * value.
  • k equals 1: you pick one card from either end. The window of size n - 1 slides through just two positions, and you compare taking the first card versus the last card.
  • Negative values in the array: the problem constraints guarantee non-negative values, but the sliding window approach would still work correctly with negative values since it minimizes the window sum.

From understanding to recall

The real lesson here is the complement reframe: picking from edges means leaving a contiguous middle behind. Once you see that, the solution is a textbook fixed-size sliding window. But seeing it under interview pressure is the hard part. You need the pattern to be automatic, not something you rediscover each time.

Spaced repetition builds that automaticity. You practice recognizing when "pick from edges" means "minimize the middle," and you practice writing the sliding window loop with its add-one-subtract-one update. After a few rounds at increasing intervals, the connection fires instantly when you see a similar problem.

CodeBricks breaks this problem into its complement-reframe and fixed-size-window building blocks, then drills each one independently. You type the window loop from memory until the index math is second nature. When a card-picking or edge-selection question appears in your interview, you do not need to stare at the problem hoping for an insight. You recognize the pattern and write the solution.

Related posts

Picking cards from the edges of an array is a satisfying puzzle once you see the sliding window trick behind it. CodeBricks helps you internalize that trick so it is ready when you need it.