🧠
Sliding Window on the Middle Subarray
💡 This approach uses a clever insight: instead of picking k cards from the ends, find the minimum sum subarray of length n-k in the middle and subtract it from the total sum to get the maximum points.
Intuition
Total points are fixed. Removing a contiguous subarray of length n-k from the middle leaves k cards from the ends. Minimizing the middle subarray sum maximizes the points taken.
Algorithm
- Calculate total sum of all cards.
- Use a sliding window of size n-k to find the minimum sum subarray.
- Subtract the minimum subarray sum from total sum.
- Return the result as maximum points.
💡 This approach reduces the problem to a classic sliding window minimum sum problem, which is efficient and elegant.
def maxScore(cardPoints, k):
n = len(cardPoints)
total = sum(cardPoints)
window_size = n - k
current_sum = sum(cardPoints[:window_size])
min_subarray_sum = current_sum
for i in range(window_size, n):
current_sum += cardPoints[i] - cardPoints[i - window_size]
if current_sum < min_subarray_sum:
min_subarray_sum = current_sum
return total - min_subarray_sum
# Example usage
if __name__ == '__main__':
print(maxScore([1,2,3,4,5,6,1], 3)) # Output: 12
Line Notes
total = sum(cardPoints)Calculate total points to use as base
window_size = n - kSize of subarray to exclude
current_sum = sum(cardPoints[:window_size])Initialize sliding window sum
current_sum += cardPoints[i] - cardPoints[i - window_size]Slide window by adding new and removing old element
public class Solution {
public static int maxScore(int[] cardPoints, int k) {
int n = cardPoints.length;
int total = 0;
for (int point : cardPoints) total += point;
int windowSize = n - k;
int currentSum = 0;
for (int i = 0; i < windowSize; i++) {
currentSum += cardPoints[i];
}
int minSubarraySum = currentSum;
for (int i = windowSize; i < n; i++) {
currentSum += cardPoints[i] - cardPoints[i - windowSize];
if (currentSum < minSubarraySum) {
minSubarraySum = currentSum;
}
}
return total - minSubarraySum;
}
public static void main(String[] args) {
System.out.println(maxScore(new int[]{1,2,3,4,5,6,1}, 3)); // 12
}
}
Line Notes
int total = 0;Initialize total sum accumulator
for (int point : cardPoints) total += point;Sum all card points
int windowSize = n - k;Calculate size of subarray to exclude
currentSum += cardPoints[i] - cardPoints[i - windowSize];Update sliding window sum by removing left and adding right
#include <iostream>
#include <vector>
using namespace std;
int maxScore(vector<int>& cardPoints, int k) {
int n = cardPoints.size();
int total = 0;
for (int point : cardPoints) total += point;
int windowSize = n - k;
int currentSum = 0;
for (int i = 0; i < windowSize; i++) {
currentSum += cardPoints[i];
}
int minSubarraySum = currentSum;
for (int i = windowSize; i < n; i++) {
currentSum += cardPoints[i] - cardPoints[i - windowSize];
if (currentSum < minSubarraySum) {
minSubarraySum = currentSum;
}
}
return total - minSubarraySum;
}
int main() {
vector<int> cardPoints = {1,2,3,4,5,6,1};
cout << maxScore(cardPoints, 3) << endl; // 12
return 0;
}
Line Notes
int total = 0;Initialize total sum variable
for (int point : cardPoints) total += point;Sum all elements in the vector
int windowSize = n - k;Calculate length of subarray to exclude
currentSum += cardPoints[i] - cardPoints[i - windowSize];Slide window by adding new and removing old element
function maxScore(cardPoints, k) {
const n = cardPoints.length;
const total = cardPoints.reduce((a, b) => a + b, 0);
const windowSize = n - k;
let currentSum = 0;
for (let i = 0; i < windowSize; i++) {
currentSum += cardPoints[i];
}
let minSubarraySum = currentSum;
for (let i = windowSize; i < n; i++) {
currentSum += cardPoints[i] - cardPoints[i - windowSize];
if (currentSum < minSubarraySum) {
minSubarraySum = currentSum;
}
}
return total - minSubarraySum;
}
// Example usage
console.log(maxScore([1,2,3,4,5,6,1], 3)); // 12
Line Notes
const total = cardPoints.reduce((a, b) => a + b, 0);Sum all card points using reduce
const windowSize = n - k;Calculate size of subarray to exclude
for (let i = 0; i < windowSize; i++) { currentSum += cardPoints[i]; }Initialize sliding window sum
currentSum += cardPoints[i] - cardPoints[i - windowSize];Slide window by adding new and removing old element
We compute total sum once and use a sliding window of size n-k to find minimum subarray sum in O(n) time and O(1) space.
💡 For n=100000, this approach does about 100000 operations, which is very efficient and suitable for interviews.
Interview Verdict: Accepted
This is the optimal approach, combining insight and efficiency, and is the best solution to implement in interviews.