1423. Maximum Points You Can Obtain from Cards
There are several cards arranged in a row, and each card has an associated number of points. The points are given in the integer array cardPoints
.
In one step, you can take one card from the beginning or from the end of the row. You have to take exactly cards.
Your score is the sum of the points of the cards you have taken.
Given the integer array cardPoints
and the integer , return the maximum score you can obtain.
Example 1:
Input: cardPoints = [1,2,3,4,5,6,1]
, k = 3
Output:
Explanation: After the first step, your score will always be . However, choosing the rightmost card first will maximize your total score. The optimal strategy is to take the three cards on the right, giving a final score of .
Example 2:
Input: cardPoints = [2,2,2]
, k = 2
Output:
Explanation: Regardless of which two cards you take, your score will always be .
Example 3:
Input: cardPoints = [9,7,7,9,7,7,9]
, k = 7
Output:
Explanation: You have to take all the cards. Your score is the sum of points of all cards.
Constraints:
-
cardPoints.length
-
cardPoints[i]
-
cardPoints.length
Solution
Brute Force
First, we can make the observation that there are only different choices of cards if we take exactly cards. Let's assume we took exactly cards from the left. The number of cards we take from the right will be fixed as we'll take cards on the right to reach a total of cards.
For each choice of cards, we can just iterate through the cards and find the sum. To find the maximum sum, we'll repeat this process for all choices. This solution will run in .
Full Solution
Let's look at two different choices of cards. The first choice will be to take cards from the left and cards from the right. The second choice will be to take cards from the left and cards from the right. Instead of recalculating the sum for the second choice, we can adjust the sum from the first choice to be the second choice. We can notice that the difference between these two choices is that we added a card on the right side and we removed a card from the left side. By applying these changes, we can transition between two choices in instead of .
Example
cardPoints = [1,2,3,4,5,6,1]
, k = 3
Let's look at the transition between two different choices in this example. Our first choice consists of cards on the left and card on the right. Our second choice will consist of card on the left and cards on the right.
The sum with our first choice is currently . Going from our first choice to our second choice, our left side lost a card and our right side gained a card. Specifically, we lost cardPoints[1] = 2
and we gained cardPoints[5] = 6
. After removing cardPoints[1]
and adding cardPoints[5]
, we obtain a sum of for our second choice.
We can implement this with the idea of two pointers. We'll use the pointers to indicate which cards we picked on the left and right side. A simple way to implement this with two pointers is to start with picking all cards on the left. For each transition, we'll remove one card on the left and add one card on the right. We keep repeating this process until we reach the choice where all our cards are picked from the right.
Time Complexity
We'll require to calculate the sum for the first choice. In addition, it will take another process all choices. Thus, our final time complexity will be .
Time Complexity: .
Space Complexity
Since we use two pointers to maintain the sum of every choice, our space complexity is .
Space Complexity: .
C++ Solution
class Solution {
public:
int maxScore(vector<int>& cardPoints, int k) {
int n = cardPoints.size();
int leftSum = 0;
for (int i = 0; i < k;
i++) { // calculate sum where all cards on the left side
leftSum += cardPoints[i];
}
int rightSum = 0;
int rightIndex = n; // pointer for the right cards
int ans = leftSum;
for (int leftIndex = k - 1; leftIndex >= 0;
leftIndex--) { // pointer for the left cards
leftSum -= cardPoints[leftIndex]; // transition between choices
rightIndex--;
rightSum += cardPoints[rightIndex];
ans = max(ans, leftSum + rightSum);
}
return ans;
}
};
Java Solution
class Solution {
public int maxScore(int[] cardPoints, int k) {
int n = cardPoints.length;
int leftSum = 0;
for (int i = 0; i < k;
i++) { // calculate sum where all cards on the left side
leftSum += cardPoints[i];
}
int rightSum = 0;
int rightIndex = n; // pointer for the right cards
int ans = leftSum;
for (int leftIndex = k - 1; leftIndex >= 0;
leftIndex--) { // pointer for the left cards
leftSum -= cardPoints[leftIndex]; // transition between choices
rightIndex--;
rightSum += cardPoints[rightIndex];
ans = Math.max(ans, leftSum + rightSum);
}
return ans;
}
}
Python Solution
class Solution: def maxScore(self, cardPoints: List[int], k: int) -> int: n = len(cardPoints) leftSum = 0 for i in range(k): # calculate sum where all cards on the left side leftSum += cardPoints[i] rightSum = 0 rightIndex = n # pointer for the right cards ans = leftSum for leftIndex in range(k - 1, -1, -1): # pointer for the left cards leftSum -= cardPoints[leftIndex] # transition between choices rightIndex -= 1 rightSum += cardPoints[rightIndex] ans = max(ans, leftSum + rightSum) return ans
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorWhat are the two properties the problem needs to have for dynamic programming to be applicable? (Select 2)
Recommended Readings
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!