
Problem Statement
In this problem, you are provided with an array of integers named nums
. Your objective is to maximize the number of points you accumulate by repeatedly performing a specific operation. The operation involves selecting an item nums[i]
from the array, deleting it, and earning points equal to the value of nums[i]
. However, the operation comes with a constraint: upon picking and deleting nums[i]
, every other element in the array that has a value of either nums[i]-1
or nums[i]+1
must also be deleted immediately, although they do not contribute to the point score. The challenge is to determine the maximum total points that can be achieved by applying this operation as many times as needed. The problem demands a solution that does not simply involve maximizing point gain in each step but rather maximizing the total gain by strategically choosing elements for deletion, accounting for their surrounding impacts.
Examples
Example 1
Input:
nums = [3,4,2]
Output:
6
Explanation:
You can perform the following operations: - Delete 4 to earn 4 points. Consequently, 3 is also deleted. nums = [2]. - Delete 2 to earn 2 points. nums = []. You earn a total of 6 points.
Example 2
Input:
nums = [2,2,3,3,3,4]
Output:
9
Explanation:
You can perform the following operations: - Delete a 3 to earn 3 points. All 2's and 4's are also deleted. nums = [3,3]. - Delete a 3 again to earn 3 points. nums = [3]. - Delete a 3 once more to earn 3 points. nums = []. You earn a total of 9 points.
Constraints
1 <= nums.length <= 2 * 104
1 <= nums[i] <= 104
Approach and Intuition
The key to solving this problem efficiently lies in recognizing that it resembles the "house robber" problem, where one cannot rob two adjacent houses. Here, points from two adjacent numbers in sorted order cannot be taken together.
Dynamic Programming for Optimized Point Collection:
- Convert the task into a dynamic programming problem where the state represents the maximum points obtainable from the first
i
unique numbers. - Utilize a hashmap or an array to keep track of the total points available from each unique number in
nums
by summing occurrences of each number. - Create a DP array
dp
wheredp[i]
will represent the maximum score obtainable using numbers from 1 toi
.
- Convert the task into a dynamic programming problem where the state represents the maximum points obtainable from the first
Base Cases and Transitions:
- If only one number is available (
k
), then the maximum points are simply the total value of all occurrences of that number. - For each number
k
encountered innums
, relate its value to either takingk
(and not takingk-1
) or not takingk
at all. This relationship is described by the equation:dp[k] = max(dp[k-1], dp[k-2] + k * count[k])
Wheredp[k-1]
is the maximum points without takingk
anddp[k-2] + k * count[k]
symbolizes taking thek
value into account along with the points fromk
taking its frequency into consideration and excludingk-1
.
- If only one number is available (
Iterating through Possibilities:
- To ensure all bases are covered, iterate from the lowest to the highest number found in
nums
, applying the above recurrence to fill thedp
array.
- To ensure all bases are covered, iterate from the lowest to the highest number found in
Return the Result:
- The answer to the problem would then be found in
dp[x]
wherex
is the maximum value innums
.
- The answer to the problem would then be found in
By following this approach, where we use dynamic programming to balance between choosing numbers and maximizing points, we can efficiently achieve the solution to the problem, even for large arrays. The examples provided illustrate how this strategy plays out with different configurations of nums
.
Solutions
- Java
- Python
class Solution {
public int removeAndProfit(int[] elements) {
int highestValue = 0;
HashMap<Integer, Integer> valueMap = new HashMap<>();
for (int element : elements) {
valueMap.put(element, valueMap.getOrDefault(element, 0) + element);
highestValue = Math.max(highestValue, element);
}
int prevPrevMax = 0;
int prevMax = 0;
int n = valueMap.size();
if (highestValue < n + n * Math.log(n) / Math.log(2)) {
prevMax = valueMap.getOrDefault(1, 0);
for (int curr = 2; curr <= highestValue; curr++) {
int temp = prevMax;
prevMax = Math.max(prevMax, prevPrevMax + valueMap.getOrDefault(curr, 0));
prevPrevMax = temp;
}
} else {
List<Integer> sortedKeys = new ArrayList<Integer>(valueMap.keySet());
Collections.sort(sortedKeys);
prevMax = valueMap.get(sortedKeys.get(0));
for (int i = 1; i < sortedKeys.size(); i++) {
int key = sortedKeys.get(i);
int tmp = prevMax;
if (key == sortedKeys.get(i - 1) + 1) {
prevMax = Math.max(prevMax, prevPrevMax + valueMap.get(key));
} else {
prevMax += valueMap.get(key);
}
prevPrevMax = tmp;
}
}
return prevMax;
}
}
The Java solution titled "Delete and Earn" involves achieving maximum profit by removing numbers from an array based on the sum of the same numbers. This Java code defines a method removeAndProfit
that accepts an array of integers and returns the maximum profit obtained. Follow the outlined logic in understanding the implementation:
- Initialize a
highestValue
to store the maximum element from the array. - Use a
HashMap
,valueMap
, to keep track of cumulative values of each unique element in the input array. - Populate these two by iterating over the elements array.
To determine the maximum points achievable:
- Initialize two variables,
prevPrevMax
andprevMax
, to help track the best score while iterating through possible numbers. - Compare
highestValue
with another calculated condition to decide the approach:- If
highestValue
is less than the logarithm-based condition, iterate linearly from2
up tohighestValue.
UpdateprevMax
andprevPrevMax
accordingly to get the maximum profit without selecting two adjacent numbers. - If not, sort the keys of the
valueMap
, and apply dynamic programming using sorted keys, updatingprevMax
andprevPrevMax
based on adjacent keys comparison.
- If
- Return
prevMax
as the solution for maximum profit after evaluating all possible cases.
Carefully designed to optimize performance based on the size and range of the input array, this approach leverages dynamic programming and condition-based strategy to efficiently solve the problem ensuring neither excessively consuming resources nor missing out on higher profits available through combined non-adjacent selections.
class Solution:
def removeAndAccumulate(self, numbers: List[int]) -> int:
score = defaultdict(int)
maximum_value = 0
for value in numbers:
score[value] += value
maximum_value = max(maximum_value, value)
prev_two = prev_one = 0
count = len(score)
if maximum_value < count + count * log(count, 2):
prev_one = score[1]
for value in range(2, maximum_value + 1):
prev_two, prev_one = prev_one, max(prev_one, prev_two + score[value])
else:
sorted_keys = sorted(score.keys())
prev_one = score[sorted_keys[0]]
for idx in range(1, len(sorted_keys)):
current_key = sorted_keys[idx]
if current_key == sorted_keys[idx - 1] + 1:
prev_two, prev_one = prev_one, max(prev_one, prev_two + score[current_key])
else:
prev_two, prev_one = prev_one, prev_one + score[current_key]
return prev_one
In the "Delete and Earn" problem, the implemented function in Python called removeAndAccumulate
calculates the maximum points you can earn by deleting numbers from a list, under certain conditions. Here's an overview of how the solution operates:
The function initializes a dictionary
score
to keep a cumulative sum of each integer as a key and its total value as the score you earn for deleting that number. It also maintains a variablemaximum_value
to track the highest number in the input list.The main logic iterates over the input list
numbers
, updatingscore
andmaximum_value
accordingly.Depending on the relationship between
maximum_value
and a calculated threshold involving the count of unique numbers, the function uses dynamic programming with two approaches:- If the maximum value is less than the sum of unique numbers and a logarithmically scaled value of their count, it uses a straightforward dynamic programming iteration over a range from
1
tomaximum_value
. - If greater, the keys of
score
are sorted, and the function then applies a dynamic programming approach that accounts for whether consecutive numbers are processed, helping avoid sub-optimal point collections when adjacent numbers are hit.
- If the maximum value is less than the sum of unique numbers and a logarithmically scaled value of their count, it uses a straightforward dynamic programming iteration over a range from
To implement this dynamic programming strategy, the solution keeps track of points you could earn by checking two previous states (
prev_two
andprev_one
) which help in deciding whether to skip a number or take it.Finally, the function returns
prev_one
, which represents the maximum score that can be obtained.
This Python function effectively utilizes dictionaries for efficient scoring and sorting, along with dynamic programming for optimal decision-making based on previous states. This approach ensures that you maximize the points based on deleting numbers according to the given rules.
No comments yet.