Problem Statement
Maximum Points You Can Obtain from Cards
Picture a row of cards laid out left to right. Each card has a number of points on it. On each turn you grab one card, but only from the very left end or the very right end of the row. You take exactly k cards, and you want the points you grab to add up to as much as possible. Here is the trick that makes this easy: if you take k cards from the two ends, the cards you leave behind always sit together in one unbroken stretch in the middle. That leftover stretch is called a contiguous window, meaning a run of neighboring cards with no gaps. So instead of thinking about all the ways to grab from the ends, you can flip the problem around: leave the cheapest middle window, and your score is the total of all cards minus that cheapest middle. Or, simpler still, you can use a sliding window directly on the k cards you take. A sliding window is a small frame that covers a fixed group of items, and you move it along one step at a time so each move only changes one item in and one item out. That is the version we will build here.
Signals to notice
Brute force first
Try all combinations of taking from left and right. Each pick is a binary choice. That instinct is useful because it follows the prompt literally, but it usually keeps revisiting work the problem is begging you to organize.
The key insight
Instead of picking k cards from ends, think of it as leaving n-k contiguous cards in the middle. Find the minimum sum window of size n-k. Answer = totalSum - minWindowSum. The goal is not to be clever for its own sake, but to remember the one relationship that keeps the solution grounded as you move forward.
Trace it on cardPoints=[1,2,3,4,5,6,1], k=3
init: window=cards[0..2]=[1,2,3], window_sum=6, max_sum=6 (take 3 from left) i=1: remove cards[2]=3, add cards[-1]=1 -> window_sum=4; max_sum=max(6,4)=6 i=2: remove cards[1]=2, add cards[-2]=6 -> window_sum=8; max_sum=max(6,8)=8 i=3: remove cards[0]=1, add cards[-3]=5 -> window_sum=12; max_sum=max(8,12)=12 (take [5,6,1] from right) loop ends after k=3 slides; return max_sum=12
What must stay true
Taking k from the ends is equivalent to NOT taking n-k from the middle. Minimizing the middle window maximizes the taken cards. This converts a hard end-picking problem to a simple sliding window. If that remains true after every update, the rest of the reasoning has a stable place to stand.
Shape of the loop
window_sum = sum(cards[0..k-1]); max_sum = window_sum
for i in 1..k:
window_sum -= cards[k - i] # drop one from the left end
window_sum += cards[n - i] # add one from the right end
max_sum = max(max_sum, window_sum)
return max_sumPseudocode only — the full worked solution lives in the Solution tab.
Easy way to go wrong
Not seeing the complement — trying to directly model 'take from left or right' is complex. The window-on-middle approach is much simpler. Most mistakes here are not about syntax; they come from losing track of what your state, pointer, or structure is supposed to mean.